1. 核心概念
MD5 是一种哈希算法,其产生的散列值通常表示为 32位 的十六进制字符串(例如 5d41402abc4b2a76b9719d911017c592)。
2. 选择建议
结论:必须使用 CHAR(32)。
2.1 为什么不用 VARCHAR?
- 额外开销:
VARCHAR是变长字段,需要额外使用 1-2 个字节来记录字符串的长度。对于 32 位的 MD5,这就浪费了空间。 - 内存碎片:
VARCHAR在更新时,如果新值比旧值长,可能导致页分裂或产生碎片(虽然 MD5 长度固定,但VARCHAR本身的变长特性在某些内存分配场景下不如定长高效)。
2.2 为什么用 CHAR?
- 定长优势:
CHAR是固定长度。对于 MD5 这种永远是 32 个字符的数据,CHAR(32)完美匹配。 - 性能:定长字段在内存处理和磁盘读取时往往更有优势,因为引擎知道它确切的偏移量。
3. 进阶优化:BINARY(16)
如果数据量极大(如数亿行),为了节省空间和索引大小,可以考虑存储 原始二进制 数据,而不是十六进制字符串。
- 原理:MD5 本质是 128 位(16 字节)的二进制数据。32位字符串只是它的 Hex 表示(每个字节变2个字符)。
- 做法:使用
BINARY(16)类型存储。- 插入时:
UNHEX('5d4140...')将字符串转为二进制。 - 查询时:
HEX(col_name)将二进制转回字符串。
- 插入时:
- 收益:空间从 32 字节降为 16 字节,节省 50% 空间,索引更小,查询更快。
4. 总结
| 方案 | 类型 | 空间占用 | 推荐度 |
|---|---|---|---|
| 常规方案 | CHAR(32) | 32 字节 | ⭐⭐⭐⭐ (简单通用) |
| 极致优化 | BINARY(16) | 16 字节 | ⭐⭐⭐⭐⭐ (省空间) |
| 反例 | VARCHAR(32) | 33 字节 | ❌ 不推荐 |
面试回答示例: “存储 MD5 这种固定长度的数据,首选 CHAR(32),因为它定长,没有长度前缀开销,且存取效率高。 如果对空间极其敏感,我会使用 BINARY(16) 存储 MD5 的原始二进制数据,这样能节省一半的存储空间和索引大小。”