1. 数据完整性概述

数据完整性,说白了就是保证你的数据「是对的、没丢、没乱」。

我做了十几年数据架构,见过太多因为数据出问题导致的线上事故。有一次凌晨三点被叫起来,原因是某核心交易表里出现了大量「幽灵记录」——数据凭空多出来,对不上账。嗯,那晚的教训让我深刻理解了:数据完整性不是锦上添花,而是系统的生命线。

什么是数据完整性

数据完整性是指数据的准确性、一致性和可靠性在整个生命周期内得到保证的程度。它包含四个层面:

层面 说明 举个栗子
实体完整性 每行数据唯一可识别 主键不能为 NULL,不能重复
域完整性 字段值符合定义规则 年龄字段不能出现负数
引用完整性 表间关联关系正确 订单表的客户 ID 必须在客户表中存在
用户定义完整性 业务规则约束 请假结束时间必须大于开始时间

你想想看,如果订单表里有个订单指向了不存在的客户,那这个订单还能发货吗?这就是引用完整性被破坏的典型场景。

为什么数据完整性如此重要

我个人习惯把数据完整性比作「地基」。地基歪了,上面的业务逻辑再漂亮也是白搭。

  • 决策失准:报表数据不准,管理层拿到的就是错误信息。我见过某公司因为库存数据不一致,多采购了 30% 的原材料,积压资金上千万。
  • 系统崩溃:数据不一致可能导致死锁、异常甚至整个服务宕机。
  • 合规风险:金融、医疗等行业对数据完整性有硬性监管要求。数据对不上账,轻则罚款,重则吊销牌照。
  • 信任崩塌:用户发现自己的订单记录丢了、余额算错了,你觉得他还会再用你的产品吗?

核心观点:数据完整性不是 DBA 一个人的事,它是从研发、测试到运维整个链条共同的责任。谁破坏了完整性,谁就要承担后果——但最终买单的永远是用户和公司。

常见的数据损坏场景

数据损坏不是小概率事件。我这些年踩过的坑,随便列几个:

1. 并发写入冲突

两个线程同时更新同一条记录,没有加锁或使用乐观锁。结果就是「丢失更新」——其中一个写入被覆盖了。

-- 典型的丢失更新场景
-- 事务 A:读取余额 100
-- 事务 B:读取余额 100
-- 事务 A:余额 = 100 - 20 = 80,写入
-- 事务 B:余额 = 100 - 30 = 70,写入(覆盖了 A 的结果)
-- 最终余额 70,实际应该扣 50,但只扣了 30

我曾经在一个支付系统里遇到过这个问题。两个并发请求同时扣款,结果只扣了一次。虽然金额不大,但性质很严重——这属于资金安全漏洞。从那以后,所有涉及金额的操作我都强制要求使用行级锁或乐观锁机制。

2. 硬件故障

磁盘坏道、内存比特翻转、网络丢包……硬件不是 100% 可靠的。你以为数据写进去了,其实可能只写了一半。

  • 磁盘静默损坏:磁盘返回写入成功,但实际数据已经损坏。普通文件系统检测不到。
  • 内存 ECC 错误:服务器内存如果没开 ECC 校验,一个比特翻转就能让数据库崩溃。
  • 网络传输乱序:TCP 虽然保证顺序,但应用层如果没做校验,数据包可能被错误拼接。

3. 软件 Bug

代码里一个不起眼的逻辑错误,可能造成大面积数据污染。

// 一个常见的 Bug:浮点数精度丢失
double price = 0.1;
double quantity = 3;
double total = price * quantity; // 结果是 0.30000000000000004
// 如果直接存到数据库,后续对账就会差那么一点点

小技巧:涉及金额的字段,永远使用 decimal 或整数(以分为单位),别用 float/double。这个坑我帮团队填过不止一次。

4. 人为误操作

别笑,这是最常见的损坏原因。DBA 手滑执行了 DELETE FROM orders 而不是 DELETE FROM orders WHERE id = 123,这种事每天都在发生。

5. 数据迁移/同步异常

从一个库搬到另一个库,或者做主从同步时,如果校验机制不到位,很容易出现数据不一致。

  • 主从延迟导致读取到旧数据
  • 分片键选择不当导致数据分布不均
  • ETL 过程中转换逻辑出错

数据完整性保障体系

说了这么多问题,那怎么解决?我习惯从三个维度来构建防护网:

数据完整性保障体系 数据完整性保障目标 预防机制 约束 · 校验 · 规范 检测机制 校验和 · 对账 · 监控 恢复机制 备份 · 回滚 · 修复 数据库约束 主键/外键/唯一 CHECK/非空 应用层校验 参数校验 业务规则检查 校验和对比 CRC/MD5/SHA 行数/金额对账 监控告警 异常检测 实时通知 核心原则 预防为主,检测为辅,恢复兜底 三者缺一不可,形成闭环

这个体系图我每次做架构评审都会拿出来讲。预防机制是「别让问题发生」,检测机制是「出了问题能发现」,恢复机制是「发现了能修好」。三者缺一不可。

一句话总结:数据完整性不是某个工具或某个环节能搞定的,它需要从设计、开发、测试到运维全链路去构建。后面的章节,我会带你一步步把这些机制落地。