在PostgreSQL中存储多个二进制文件修订版的最有效方法是什么?

时间:2011-04-02 10:28:01

标签: database-design postgresql version-control binary diff

我在这里寻找数据库中有限形式的版本控制:

  • 大小是最重要的:同一文件的许多修订应该占用尽可能小的空间(我不是在寻找压缩,因为数据已经被压缩了)
  • 计算要求是次要的
  • 我应该能够尽快获取文档的当前版本(获取旧版本不是时间关键)

基本上答案应至少包含两件事:

  • 你会使用什么二元差异算法?
  • 您将如何以PostreSQL特有的方式构建此系统?

2 个答案:

答案 0 :(得分:5)

“大小最重要”:例如,使用bsdiff?的外部差异工具(例如PL/sh)如何。

“我应该能够尽快获取文档的当前版本”:在这种情况下,您将希望以“错误”方式进行差异化,因此每次修订都会涉及:

  1. 将'previous revision'替换为'new revision'和'previous revision'之间的差异
  2. 添加'新版本'
  3. 要回到旧修订版,则需要迭代地将先前的差异应用为补丁,直到达到所需的修订版。

    无论你做什么,我认为在使用diff工具之前你需要首先解压缩数据。原因如下:

    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 - 如果您尝试使用真实文件,我预计差异会更大。

答案 1 :(得分:3)

我倾向于真的不喜欢重新发明轮子。在存储空间优化的情况下,比我更聪明的人已经找到了解决方案。我希望,尽可能利用这些非常聪明的人的辛勤工作。有了这个说,我可能会考虑将文件存储在Mercurial或Git等修订控制系统中,一旦我理解了它们如何存储二进制数据。一旦你弄清楚你想要使用哪一个,你可以看看创建一些存储函数的方法,这些函数很可能是pl / perl或类似的,可以与版本控制系统交互,并弥合PostgreSQL中的关系数据和二进制文件之间的差距文件。

我对这种方法的唯一问题是我不喜欢我采用交易系统并在其中引入了外部系统(Mercurial / Git)。最重要的是,数据库的备份不会备份我的Mercurial或Git存储库。但是总会有一个权衡,所以只要想出你可以忍受哪些。