关于数据库:postgresql:md5 消息摘要的数据类型?

postgresql: data type for md5 message digest?

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


作为 bytea 的 md5 散列将仅使用 16 个字节而不是 32 个字节用于六进制表示:

1
2
3
4
CREATE TABLE t (d bytea);
INSERT INTO t (d) VALUES
    (digest('my_string', 'md5')),
    (decode(md5('my_string'), 'hex'));

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

1
CREATE extension pgcrypto;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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 值是存储大小。 bytea 与十六进制表示相比,它不到一半。


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

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