Каков наиболее эффективный способ хранения нескольких версий двоичных файлов в PostgreSQL? - PullRequest
5 голосов
/ 02 апреля 2011

Я ищу ограниченную форму контроля версий в базе данных здесь:

  • Размер имеет наибольшее значение: многие ревизии одного и того же файла должны занимать наименьшее возможное пространство (я не ищу сжатия, поскольку данные уже сжаты)
  • Вычислительные требования вторичны
  • Я должен быть в состоянии получить текущую версию документа как можно быстрее (выбор более старых версий не критичен ко времени)

В основном ответы должны содержать как минимум две вещи:

  • Какой двоичный алгоритм сравнения вы бы использовали?
  • Как бы вы структурировали эту систему так, как это определено для PostreSQL?

Ответы [ 2 ]

5 голосов
/ 04 апреля 2011

"Размер имеет наибольшее значение": как насчет внешнего инструмента сравнения (например, bsdiff? ), использующего, например, PL / sh .

"Я долженбыть в состоянии получить текущую ревизию документа как можно быстрее ": в этом случае вы захотите выполнить" неправильный "обход, поэтому каждая ревизия будет включать:

  1. replace 'предыдущая ревизия 'с разницей между' новой ревизией 'и' предыдущей ревизией '
  2. добавить' новую ревизию '

Чтобы вернуться к старой ревизии, потребуется многократное применение предыдущих разностейисправления, пока вы не доберетесь до нужной вам ревизии.

Что бы вы ни делали, я думаю, вам нужно будет сначала распаковать данные, прежде чем использовать инструмент сравнения.Вот почему:

dd if=/dev/urandom of=myfile.1 bs=1024 count=10
cp myfile.1 tmp; cat tmp >> myfile.1
cp myfile.1 tmp; cat tmp >> myfile.1
cp myfile.1 tmp; cat tmp >> myfile.1
cp myfile.1 tmp; cat tmp >> myfile.1
dd if=/dev/urandom of=myfile.2 bs=1024 count=10
cp myfile.2 tmp; cat tmp >> myfile.2
cp myfile.2 tmp; cat tmp >> myfile.2
cp myfile.2 tmp; cat tmp >> myfile.2
cp myfile.2 tmp; cat tmp >> myfile.2
cat myfile.1 >> myfile.2
bsdiff myfile.1 myfile.2 diff
gzip -c myfile.1 > myfile.1.gz
gzip -c myfile.2 > myfile.2.gz
bsdiff myfile.1.gz myfile.2.gz gz.diff
rm tmp
ls -l

-rw-r--r-- 1 root root  17115 2011-04-05 10:54 diff
-rw-r--r-- 1 root root  21580 2011-04-05 10:54 gz.diff
-rw-r--r-- 1 root root 163840 2011-04-05 10:54 myfile.1
-rw-r--r-- 1 root root  11709 2011-04-05 10:54 myfile.1.gz
-rw-r--r-- 1 root root 327680 2011-04-05 10:54 myfile.2
-rw-r--r-- 1 root root  23399 2011-04-05 10:54 myfile.2.gz

Обратите внимание, что gz.diff больше, чем diff - если вы попробуете это с реальными файлами, я ожидаю, что разница будет еще больше.

3 голосов
/ 02 апреля 2011

Мне очень не нравится заново изобретать колесо.В случае оптимизации дискового пространства люди гораздо умнее, чем я, уже нашли решения.Я бы предпочел, когда это возможно, использовать тяжелую работу этих действительно умных людей.С учетом сказанного я мог бы рассмотреть вопрос о хранении своих файлов в системе контроля версий, такой как Mercurial или Git, как только я пойму, как они хранят двоичные данные.Как только вы выясните, какую из них вы хотите использовать, вы сможете найти способы создания некоторых хранимых функций, наиболее вероятных в pl / perl или аналогичных, которые могут взаимодействовать с системой контроля версий и преодолеть разрыв между данными ваших отношений в PostgreSQL и двоичнымфайлы.

Моя единственная проблема с этим подходом заключается в том, что мне не очень нравится, что я взял транзакционную систему и ввел в нее внешнюю систему (Mercurial / Git).И, кроме того, резервная копия базы данных не создаст резервную копию моего хранилища Mercurial или Git.Но всегда найдется компромисс, поэтому просто подумайте, с какими вы можете жить.

...