在数据库日常运维和数据处理开发中,经常需要验证单条数据的完整性,防止数据在传输、同步或者存储过程中被意外修改。生成行级的校验和是一种轻量且高效的验证方式,主流数据库都提供了对应的函数支持,其中最常用的是CHECKSUM函数和MD5函数,两种函数适用场景各有不同。

CHECKSUM函数生成行级校验和
CHECKSUM是SQL Server等数据库内置的校验和函数,能够快速计算一行或者多个字段的校验值,返回的是一个整数类型的校验结果,计算效率较高,适合对性能要求较高的场景。
基本语法
CHECKSUM函数可以接收多个字段作为参数,计算这些字段组合后的校验和,语法格式如下:
-- 计算单个字段的校验和 SELECT CHECKSUM(column_name) AS row_checksum, * FROM table_name; -- 计算多个字段组合的校验和 SELECT CHECKSUM(column1, column2, column3) AS row_checksum, * FROM table_name;
实际示例
假设存在一张用户表user_info,包含user_id、user_name、age三个字段,需要为每一行生成基于这三个字段的校验和,可以使用以下查询:
-- 查询用户表每行的校验和
SELECT
CHECKSUM(user_id, user_name, age) AS row_checksum,
user_id,
user_name,
age
FROM user_info;
注意事项
- CHECKSUM函数计算速度很快,但存在一定的哈希碰撞概率,也就是不同的字段组合可能得到相同的校验和,因此不适合对数据准确性要求极高的场景。
- 如果字段值为NULL,CHECKSUM函数会将其作为0参与计算,修改字段为NULL或者从NULL改为具体值都会影响最终的校验和结果。
MD5函数生成行级校验和
MD5是一种广泛使用的哈希算法,多数数据库都支持MD5函数,它会生成固定长度的32位十六进制字符串作为校验值,碰撞概率极低,适合对数据准确性要求高的场景。
基本语法
MD5函数通常接收字符串作为参数,因此需要先将行的多个字段拼接成字符串再计算,语法格式如下:
-- 拼接多个字段后计算MD5校验和 SELECT MD5(CONCAT(column1, column2, column3)) AS row_md5, * FROM table_name;
实际示例
同样针对user_info表,使用MD5函数生成行级校验和的查询如下:
-- 查询用户表每行的MD5校验和
SELECT
MD5(CONCAT(user_id, user_name, age)) AS row_md5,
user_id,
user_name,
age
FROM user_info;
注意事项
- MD5计算速度比CHECKSUM慢,生成的是字符串类型的校验值,存储空间占用比CHECKSUM的整数类型更大。
- 拼接字段时需要注意字段的分隔,避免不同字段组合拼接后出现相同的字符串,比如字段A值为
12、字段B值为3,和字段A值为1、字段B值为23,直接拼接都会得到123,可以在拼接时加入固定分隔符,例如CONCAT(user_id, '|', user_name, '|', age)。 - 如果字段存在NULL值,CONCAT函数会将NULL转为空字符串,需要根据业务需求决定是否处理NULL场景,避免校验结果不符合预期。
两种方式的对比选择
可以通过下表快速判断两种方式的适用场景:
| 对比维度 | CHECKSUM函数 | MD5函数 |
|---|---|---|
| 校验值类型 | 整数 | 32位十六进制字符串 |
| 计算效率 | 高 | 较低 |
| 碰撞概率 | 较高 | 极低 |
| 适用场景 | 非核心数据快速校验、性能优先场景 | 核心数据完整性校验、准确性优先场景 |
校验和的实际应用
生成的行级校验和可以存储在表中,定期重新计算校验和与原值对比,快速发现被修改的行;也可以在数据同步时,对比源库和目标库的校验和,快速定位同步不一致的行,减少全量数据比对的开销。
如果需要在其他数据库中使用类似功能,MySQL可以使用CRC32函数作为轻量校验方案,PostgreSQL可以使用md5函数或者hashtext函数实现,核心思路和上述示例一致,只需要根据对应数据库的函数语法调整即可。