代码之家  ›  专栏  ›  技术社区  ›  Donald Miner

在PostgreSQL中存储字符串的最简洁、最快速的方法

  •  1
  • Donald Miner  · 技术社区  · 14 年前

    我有一个大的十六进制(16字节,32个十六进制数字)数据项,它的格式总是:

    00d980113901429fa6de7fb7e2da705a
    

    这是来自我的源代码的ASCII字符串(即,上面的零是字符0 0x30,而不是0x00),我想知道人们对在PostgreSQL中存储这个的最佳方式(irt存储和速度)的看法。

    空间和时间是一个问题,因为我有很多这样的问题(超过一万亿)。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Tometzky    14 年前

    比较这两张10M记录表:

    create table test (a int8 not null, b int8 not null, primary key(a,b));
    insert into test
      select generate_series(1,10000000), generate_series(1,10000000);
    select pg_size_pretty(pg_total_relation_size('test'));
    
    723 MB
    
    create table test_bytea (a bytea not null);
    insert into test_bytea
      select decode(lpad(to_hex(a),16,'0')||lpad(to_hex(b),16,'0'),'hex') from test;
    alter table test_bytea add primary key (a);
    select pg_size_pretty(pg_total_relation_size('test_bytea'));
    
    804 MB
    

    A bytea 2*int8 . 这并不多,但意味着缓存中的行将减少11%。顺序扫描会慢11%等等。

    如果您的数据没有改变,也许您应该考虑使用排序值的平面文件存储而不是数据库-这将是每10M记录只有152MB,搜索将是O(log(n))。

        2
  •  1
  •   OMG Ponies    14 年前

    为了确定合适的数据类型,您必须确定数据最常用的用途。脱离数据类型的转换意味着引用该列的索引是无用的。

        3
  •  1
  •   Julius Musseau    14 年前

    我怀疑BYTEA在空间上要小2倍,在比较上要快2倍<,=)与VARCHAR表示法相比。

    在其他数据库引擎中,甚至可以避免长度头开销。例如:

    MS-SQL:   BINARY(16)
    Oracle:   RAW(16)
    MySQL:    BINARY(16)
    

    或者如果您喜欢长度标题:

    MS-SQL:   VARBINARY(16)
    Oracle:   BLOB
    MySQL:    VARBINARY(16)