【问题标题】:postgresql: data type for md5 message digest?postgresql:md5 消息摘要的数据类型?
【发布时间】:2013-04-05 15:39:27
【问题描述】:

我想使用某个字符串的 MD5 消息摘要作为表的主键。我应该为这样的字段使用什么数据类型?我应该为该领域写什么selectinsert 语句?

【问题讨论】:

    标签: database postgresql database-design


    【解决方案1】:

    bytea 的 md5 哈希将仅使用 16 个字节,而不是 32 个字节用于六进制表示:

    create table t (d bytea);
    insert into t (d) values
        (digest('my_string', 'md5')),
        (decode(md5('my_string'), 'hex'));
    

    以上两种形式都可以使用,但要使用更简单的digest 功能,需要以超级用户身份安装pgcrypto 扩展:

    create extension pgcrypto;
    

    如上使用digest函数或decodemd5的组合搜索某个字符串:

    select
        octet_length(d) ba_length,
        pg_column_size(d) ba_column,
        encode(d, 'hex') hex_representation,
        octet_length(encode(d, 'hex')) h_length,
        pg_column_size(encode(d, 'hex')) h_column
    from t
    where d = digest('my_string', 'md5')
    ;
     ba_length | ba_column |        hex_representation        | h_length | h_column 
    -----------+-----------+----------------------------------+----------+----------
            16 |        17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |       32 |       36
            16 |        17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |       32 |       36
    

    pg_column_size 值是存储大小。与 hexa 表示相比,bytea 不到一半。

    【讨论】:

      【解决方案2】:

      bytea 有 1 个字节的开销,但填充到 8 个字节会导致大量浪费。

      请考虑使用 uuid 类型,它只使用 16 个字节。选择时您必须使用REPLACE(md5::text, '-', '') as md5 之类的东西,但这应该是一个快速操作。

      【讨论】:

      • 你有“填充到 8 个字节”的参考吗?所有the docs say 是存储大小=“1 或4 字节加上实际的二进制字符串”
      • 两个问题:a) 您存储 1+16=17 字节,后续列将在 pg_type 中按 typalign 填充,b) 请参阅 this question 关于 MAXALIGN 和 page layout reference 对齐。 [“实际用户数据(行的列)从 t_hoff 指示的偏移量开始,该偏移量必须始终是平台 MAXALIGN 距离的倍数。” == 在 x64 上为 8]。
      • 在这种特定情况下,行空间使用量可能为 23+1(行标题 + 最多 8 列的空标题)+ 4 (ba_length) + 4 (ba_column) + 1+16 (hex_representation ) + 3(h_length 的对齐填充)+ 4(h_length)+ 4(h_column)= 60 + 4(行填充)。这就是比使用 uuid 多获得 1 + 3 + 4 = 8 个字节的方式。底线:如果您关心空间,则必须关心行布局。通常首先放置大字段接近最优,但如果它大于 8 个字节,您可能会重新考虑。
      • 有趣 - 虽然数字会根据表中下一列的 typalign 值而有所不同,对吧?
      • 是的,可能。一个小的变化可能会产生很大的影响,或者根本没有影响。要考虑的另一件事是,可为空的字段在特定行实例中可能不占用空间,因此,如果您要布置表格以最大程度地节省空间,则需要考虑使用和不使用它们的布局。 (当然,如果多于八列且一列为空,则空位图不再占用 23 字节标头末尾的“空闲”字节,而是由于用户数据对齐而将行大小增加了 MAXALIGN -添加列时可能会导致表大小显着且令人困惑的增加。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      相关资源
      最近更新 更多