哈希函数是什么
哈希函数把任意长度的输入压成固定长度的摘要,用于内容校验、幂等键与分片路由。MySQL 内置 MD5、SHA1、SHA2 与 CRC32;PostgreSQL 内置 md5 与 sha 系列,其它算法需要安装 pgcrypto 后调用 digest()。摘要是单向的,无法反推原文。
基本信息
| MySQL | MD5()、SHA1()、SHA2(str, 位数)、CRC32() |
|---|---|
| PostgreSQL | md5()、sha256()/sha512()、pgcrypto 扩展的 digest() |
| 返回类型 | MySQL 返回十六进制文本;PG 的 sha256 返回 bytea,需 encode |
| SHA2 位数 | 224 / 256 / 384 / 512 可选,常用 256 |
| CRC32 | 32 位整数校验值,碰撞概率高,只适合做快速粗筛 |
| 禁止用途 | 不要把 MD5、SHA1 用于签名或密码存储 |
MySQL 示例
MySQL 示例
SELECT MD5('abc'); -- 900150983cd24fb0d6963f7d28e17f72(32 位十六进制)
SELECT SHA2('abc', 256); -- 64 位十六进制字符串
SELECT SHA1('abc'); -- 40 位十六进制,已不建议用于安全场景
SELECT CRC32('abc'); -- 891568578(整数)
SELECT CHAR_LENGTH(SHA2('abc', 256)); -- 64:长度固定,与输入长短无关PostgreSQL 示例
PostgreSQL 示例
SELECT md5('abc'); -- 文本,32 位十六进制
SELECT encode(sha256(convert_to('abc','UTF8')), 'hex'); -- PG 11+ 内置,输出十六进制
-- 需要更多算法时安装扩展
CREATE EXTENSION IF NOT EXISTS pgcrypto;
SELECT encode(digest('abc', 'sha256'), 'hex'); -- 与上面结果一致用途与选择
| 场景 | 推荐做法 | 说明 |
|---|---|---|
| 内容校验 | SHA2(str,256) 或 sha256 | 比 MD5 更难构造碰撞 |
| 幂等键 | SHA2 或 MD5 | 长文本先哈希,再在摘要列建唯一索引 |
| 快速校验 | CRC32 | 非常快但易碰撞,只做粗筛 |
| 密码存储 | 不要用这些函数 | 用应用层 bcrypt、Argon2 加盐慢哈希 |
| 分片路由 | 摘要取模 | 分布均匀,重分片时迁移成本高 |
典型使用场景
- 文件或大文本内容校验,比对两端摘要是否一致
- 去重:长 URL、长文本先算摘要,再在摘要列上建唯一索引
- 生成幂等键,防止同一请求被重复写入
- 缓存键:把长参数压成定长字符串
- 分库分表路由:按摘要取模决定落到哪个分片
- 数据同步比对:只比摘要列,省掉全字段比较的开销
两库的 SHA-256 结果可以对齐,但返回形式不同:MySQL 是十六进制文本,PostgreSQL 的 sha256 是 bytea。存储与比较前统一编码格式,否则“看起来一样却查不到”。
MD5 与 SHA1 已不适合安全用途:构造碰撞的成本很低,不能用于签名、令牌或密码。抗碰撞场景用 SHA-256 及以上;密码存储用带盐的慢哈希(bcrypt、Argon2),这些不在 SQL 内置函数范围内。