某次在建表情形里你随意击键打出的约束,有望于三个月尔后的某个深沉夜晚里头,给你阻挡一回等同要冲决数据库并狼狈逃窜般地步艰难的关乎日常生产的事故,千万不要仅仅像对待答题之类的考试题目那种心态看待关于约束的这些情况,它们是为处于数据库中存在那种如阻止因愚笨错误而损毁数据库的最后保障设计。
主键约束就是身份证
作为表的唯一身份标识的是主键,在2025年时我接手过一个电商后台,订单表竟然没有主键,完全依靠代码层来保障不重复,然而结果却是同一笔订单被重复发货了三次,赔了八千多块,主键必须要同时满足非空以及唯一这两个条件,这就如同你家的门牌号一样,既不能不存在,也不能有两家同时使用。
MySQL当中运用 AUTO_INCREMENT,SQL Server 使用 IDENTITY,Oracle 从 12c 起始运用 IDENTITY 列。不要自以为是地拿业务字段当作主键,身份证号会发生变更,手机号会被注销。在 2026 年 2 月,某省政务系统由于把身份证号当作主键,离婚之后无法更改曾用名,险些没办法办理再婚登记。自增整数亦或是 UUID 才是最为稳妥的选择。
唯一约束给非主键上保险
唯一约束准许一个空值存在,然而仅能有一个是这样哦。在2024年双十一,于某生鲜平台的优惠券表格里面,唯一约束被设定在了“用户ID加上优惠券类型”这儿,结果呢运营人员居然手动给一名用户插入了两张相同类型的券,那第二张由于违反了唯一约束所以就没能发出去。这事儿之后一调查,本来应该是每个人限制领取一张的,要是没有这个约束的话就会损失三十多万呢。
具备唯一约束添加要求的诸般字段,诸如身份证号、手机号以及车牌号,均是必须予以添加的。切不可寄希望于业务逻辑能够将所有重复情形阻拦住——毕竟操弄途径永远存在你所未能预想周全的状况。于2019年出现爆雷情形的深圳一家P2P,在事后审计过程当中,赫然察觉到借款人一众列表内容里存在三百多条完全毫无二致的身份证记录,然而系统范围之内却并未有任何唯一约束的相关设置对其进行阻拦。
检查约束堵住脏数据入口
检查约束乃是为列添加守门员,2025年,杭州有一家互联网医疗公司上线了电子病历系统,其中年龄字段竟然允许负数这个情况出现,当护士在录入时不小心误触了键盘,使得一个五岁为负数即 -5岁的病人成功地建立了档案,进而导致后续所有涉及年龄统计的报表都出现了错误,后来添加了CHECK(age BETWEEN 0 AND 150)这种设置,此类低级错误便根本无法进入系统了。
邮箱应当带有@,手机号务必为11位,性别仅能用男或者女,这些规则要直接通过检查约束固定写在数据库里,千万别依赖前端校验,因为总会存在绕过页面的插入操作,上海某金融科技公司的后台管理工具由于没在数据库层面限定金额必须大于0,测试人员向里插入了一笔-500块的交易,致使日终清算直接崩溃了。
默认约束省下重复劳动
默认约束所解决掉情形乃是“大部分状况均相同”的那种场景 ,在2024年的时候 ,顺丰于内部安排了一次针对某个物流系统的改动 ,在这样变动当中呀 ,包裹表内的 “承运商” 这个字段呢 ,有90%其所显示的都是顺丰速运 ,那些进行开发的工作人员呀 ,在代码层次将这个取值予以了写程序固定 ,后来呢 ,公司方面又增添进来顺丰同城业务这款东西呀 ,改动了代码的同时却遗漏掉去更新历史数据的默认逻辑的这件事 ,致使新的数据跟老的数据杂糅到了一起 ,就导致了报表出现了对不上账目这种状况。
地址填写为“不详”,创建时间选取当前的时刻,状态设置成“待支付”——这些情况要是能够使用默认约束的话,那就别交付给应用层去处理。要记住这么一点哦:默认值是在进行插入操作的时候才会起到作用的,而不是在修改的时候。要是用户后续填写了真实的地址,原来设置的默认值就会被覆盖掉,这样就不会造成历史数据被污染喽有。
外键约束保关系也拖性能
两张表的有序关联,被迫由外键来强力维系。在二零一九年的时候,我曾任职过的公司,订单明细表内存有订单标识,然而订单主表之中与之对应的那条记录被删除掉了,明细表内却依旧留存着。财务展开对账之时,发觉一笔款项已经支付出去了,可是与之相关联的订单却已然不存在了,经过连续三天的追踪查究,最终查明原来是实习生直接在数据库里将主表记录给删除掉了。
但外键并非是必须要有的。阿里Java开发手册明确表示禁止使用外键,要求全部在应用层进行维护。这是为什么呢?因为在高并发的情况下,外键检查会导致锁表,当每秒有几千笔交易的时候根本承受不住。在2023年的时候,拼多多对架构进行了调整,将核心订单表的外键全部去除了,采用定时任务扫脏数据来进行替代。小项目是可以保留外键的,而日活数量如果超过百万就不要使用了。
删除更新策略选错就是灾难
设置在外键约束之中的ON DELETE以及ON UPDATE,要是选错了那么后果将会十分严重。在二零二二年的南京某一家装平台 ,设计师表更改了主键ID ,与之关联的案例表所设置的是ON UPDATE CASCADE ,于是案例全部都自动关联到了新的ID ,数据并未丢失。然而要是当时选择的是NO ACTION ,所有的案例都必须得手动去修改。
最具危险性情形乃ON DELETE CASCADE,删了一位用户以后,会将与之相关的订单、评论以及积分一并彻底删除干净,在2018年时,于某招聘网站,运维人员于删除测试数据之际,忘却了WHERE条件,仅一条DELETE语句便致使正式用户连同其投递记录完全遭到物理删除,恢复工作耗费了六个小时,较为稳妥的做法则是进行逻辑删除,增添一个is_deleted字段,即便真的打算删除数据,也应先采用SELECT操作以此确认受影响的行数,做到心中有数,方可进行后续操作。
参与实际项目期间,你是否曾因欠缺约束而遭受损失,又或者因错误添加外键策略而引发问题?在评论区分享你的经历,点赞并收藏本文,下次于设计表结构之前将其找出查看一番。

Comments NOTHING