是的。哈希摘要通常存储为十六进制数字的 ASCII 表示,例如单词“哈希”的 MD5 是:
0800fc577294c34e0b28ad2839435945
这是一个 32 个字符的 ASCII 字符串。
但是 MD5 确实产生了一个 128 位的二进制哈希值。这应该只需要 16 个字节来存储为二进制值而不是十六进制数字。所以你可以通过使用二进制字符串来获得一些空间效率。
CREATE TABLE test.foobar (
id BINARY(16) NOT NULL PRIMARY KEY
);
INSERT INTO test.foobar (id) VALUES (UNHEX(MD5('hash')));
回复。你的 cmets 你更关心性能而不是空间效率:
我不知道 BINARY 数据类型比 CHAR 更快的任何原因。
如果您有效地使用缓存缓冲区,那么大小只有一半可以提高性能。也就是说,如果字符串是存储相同十六进制值所需的 CHAR 大小的一半,则给定数量的高速缓存内存可以存储两倍多的 BINARY 数据行。同样,该列上索引的缓存内存可以存储两倍。
结果是更有效的缓存,因为随机查询更有可能命中缓存的数据或索引,而不是需要磁盘访问。缓存效率对于大多数数据库应用程序来说都很重要,因为通常瓶颈是磁盘 I/O。如果您可以使用缓存来降低磁盘 I/O 的频率,那么这比在一种数据类型或另一种数据类型之间进行选择更划算。
至于存储在 BINARY 中的哈希字符串与 BIGINT 之间的区别,我会选择 BIGINT。缓存效率会更高,而且在 64 位处理器上整数运算和比较应该非常快。
我没有测量数据来支持上述说法。选择一种数据类型而不是另一种数据类型的净收益很大程度上取决于数据库和应用程序中的数据模式和查询类型。要获得最准确的答案,您必须尝试两种解决方案并衡量差异。
回复。您假设二进制字符串比较比默认的不区分大小写的字符串比较更快,我尝试了以下测试:
mysql> SELECT BENCHMARK(100000000, 'foo' = 'FOO');
1 row in set (5.13 sec)
mysql> SELECT BENCHMARK(100000000, 'foo' = BINARY 'FOO');
1 row in set (4.23 sec)
所以二进制字符串比较比不区分大小写的字符串比较快 17.5%。但请注意,在对这个表达式求值 1 亿次之后,总的差异仍然不到 1 秒。虽然我们可以测量速度的相对差异,但速度的绝对差异确实是微不足道的。
所以我再重申一遍:
- 衡量,不要猜测或假设。你有根据的猜测在很多时候都是错误的。在您进行每次更改之前和之后进行测量,这样您就知道它有多大帮助。
- 将您的时间和精力投入到获得最大收益的地方。
- 不要为小事出汗。当然,只要有足够的迭代次数,微小的差异就会累加起来,但考虑到这些迭代次数,具有更大绝对收益的性能改进仍然是可取的。