Мой случай:Append бинарное содержимое в колонке BYTEA в базе данных PostgreSQL
У меня есть некоторые двоичные данные, которые были разбиты на множество частей. Специальная таблица FileParts
содержит fileId
, partNo
и data
.
Мне нужно собрать все детали в другой стол MyFilesStorage
.
Теперь я буду выбирать между двумя реализациями:
DO $CODE$
declare
r record;
begin
UPDATE public.MyFilesStorage SET mainFileData = E''::bytea WHERE id = 'e14a26c0-db4b-47e1-8b66-e091fb3ba199'::uuid;
for r in (select data
from public.FileParts
where fileId = '89cb8598-436b-49b3-bb1c-34534c6d068e'::uuid
order by partNo) loop
UPDATE public.MyFilesStorage SET mainFileData = mainFileData || r.data WHERE id = 'e14a26c0-db4b-47e1-8b66-e091fb3ba199'::uuid;
end loop;
end;
$CODE$
я установить данные, как пустые, то читать части по одному и добавить каждую часть в основную таблицу.
Другой вариант:
DO $CODE$
declare
r record;
p_result bytea;
begin
p_result = E''::bytea;
for r in (select data
from public.FileParts
where fileId = '89cb8598-436b-49b3-bb1c-34534c6d068e'::uuid
order by partNo) loop
p_result = p_result || r.data;
end loop;
UPDATE public.MyFilesStorage SET mainFileData = p_result WHERE id = 'e14a26c0-db4b-47e1-8b66-e091fb3ba199'::uuid;
end;
$CODE$
Здесь я использую переменную TEMP. Во-вторых, гораздо быстрее, но я не знаю, что займет больше памяти? Сначала мне нужна память для загрузки всего файла в ОЗУ, и как насчет первого? Будет ли postgre загружать весь контент здесь: mainFileData = mainFileData || r.data
?
Возможно, существует другой способ сделать это, потому что оба варианта: veeeeery slow? В oracle я использую DBMS_LOB.APPEND
для этой операции.
Вы можете использовать функцию больших объектов PostgreSQL, и в этом случае вы можете быстро добавить приложение, стремясь к концу и письму. http://www.postgresql.org/docs/9.1/interactive/lo-interfaces.html#LO-SEEK У этого есть некоторые ограничения по сравнению с bytea, поэтому внимательно изучите его.С другой стороны, то, что вы делаете с частями файла, очень похоже на то, что PostgreSQL делает внутренне через систему TOAST, за исключением того, что она также пытается выполнить сжатие по умолчанию. http://www.postgresql.org/docs/9.1/interactive/storage-toast.html Это полностью автоматическое и прозрачное. – kgrittn
Большое спасибо. Это очень полезный совет! Я попробую интерфейс LO. – Yavanosta