您好,欢迎访问数据库运维|优化|安装|迁移|服务官网!
13261661949
数据库约束不会用?一文详解常见约束与实战案例-数据资讯-数据库运维|优化|安装|迁移|服务_uDBok.com

新闻动态

联系我们

数据库约束不会用?一文详解常见约束与实战案例-数据资讯-数据库运维|优化|安装|迁移|服务_uDBok.com

地址:北京市昌平区高新经济开发区
手机:13261661949

咨询热线13261661949

数据库约束不会用?一文详解常见约束与实战案例

发布时间:2026-08-30 13:03:00人气:1656

前两天一个做后端的朋友跟我吐槽,说他们项目里数据乱得跟菜市场似的,用户表里居然能存负数年龄,订单表里的金额还能是空值。我问他建表的时候干嘛不加约束,他愣了半天反问我:“约束?那玩意儿不就是写几个关键字的事吗,加了有啥用?”这话我听了不下十遍,今天干脆把数据库约束这摊子事掰开揉碎了讲清楚,顺便给你几个能直接抄走的实战案例。Check for duplicate words: "的"? Not. "了"? Not. "是"? Not. Remove extra punctuation? There's a full-width colon? Actually quotes are Chinese. It's fine. Maybe remove extra "的" duplicates? There's "的" okay. "顺便给你几个能直接抄走的实战案例。" fine.Paragraph 2:

数据库约束不会用?一文详解常见约束与实战案例

先搞清楚约束到底在防什么。数据库这东西,本质就是个装数据的仓库,但你要是啥都不管往里塞,不出一个月,垃圾数据就能把你淹没。约束就是仓库门口的安检员,不合格的包裹直接拦下。最常见的五种约束,主键约束保证每一行都有唯一身份,外键约束管住表跟表之间的关系,唯一约束防止重复数据,检查约束限定取值范围,非空约束拒绝空值。听着简单,但真正用对的人真不多。Check duplicates: "的"? Not. "了"? Not. "是"? Not. Maybe "的"? There's "的" but not duplicate. "真正用对的人真不多" okay.Paragraph3:

我见过太多人把主键当摆设。有个电商项目,订单表主键用的是自增ID,这本身没问题,但他们居然没加唯一约束,结果同一条订单因为代码bug被插入了两次,用户下单两件商品,后台却生成了四条记录。等到对账的时候,财务差点把开发骂哭。其实解决这个问题就一行SQL的事,在主键字段上再加个UNIQUE,或者干脆把订单号设计成业务主键,比如“20240615-0001”这种格式,再用数据库的唯一约束兜底,从根上杜绝重复。Check duplicates: "的"? Not. "了"? Not. "是"? Not. "居然没加唯一约束" fine.Paragraph4:

外键约束更是个让人又爱又恨的东西。爱它是因为它能保证两张表的数据对得上,恨它是因为用不好会拖垮性能。我有个客户,他们的订单表和商品表做了外键关联,结果每次插入订单都要去校验商品是否存在,高峰期每秒上千的并发,数据库直接被打爆。后来我们把外键校验挪到了应用层,数据库只保留索引,性能瞬间上去了。但这里得提醒你,外键约束不是不能用,而是要看场景。低频管理系统,外键能帮你省掉大量代码逻辑;高并发核心链路,能不用就别用,出了事你兜不住。Check duplicates: "的"? Not. "了"? Not. "是"? Not. "能不用就别用" fine.Paragraph5:

检查约束是最被低估的一个。很多人不知道,MYSQL 8.0之前压根不支持CHECK约束,所以老项目里经常能看到数据校验全靠代码写。但代码这东西,总有漏网之鱼。比如有个招聘系统,简历表里的期望薪资字段,前端明明做了校验,但有人直接调接口往数据库里塞了个负数,后端也没拦,结果候选人面试的时候,HR看到的薪资是负的,场面一度十分尴尬。其实加一行CONSTRAINT chksalary CHECK (expectedsalary > 0),这类问题就不会发生。还有状态字段,比如订单状态只能用“待支付”“已取消”这几种,加个IN检查,比你在代码里写十层判断都靠谱。Check duplicates: maybe "的"? Not. "了"? Not. "是"? Not. "加个IN检查" fine.Paragraph6:

非空约束看起来最简单,但坑最多。很多人觉得字段默认值就能解决空值问题,但默认值跟非空是两码事。比如用户表的注册时间字段,你设了DEFAULT CURRENTTIMESTAMP,但万一有人显式插入NULL呢?数据库照样收下。所以该加NOT NULL的地方一个都不能省。我见过一个CRM系统,客户表的负责人字段没加非空约束,结果离职员工的客户记录全成了无主数据,新来的销售想接管都找不到入口,只能靠脚本一个个补。Check duplicates: "的"? Not. "了"? Not. "是"? Not.Paragraph7:

说个实战案例。之前帮一个物流公司做过一个快递单号管理模块,他们的需求是单号必须唯一、必须符合特定格式、不能为空、而且关联的客户必须存在。当时我建表是这么写的:

CREATE TABLE waybill (

id INT PRIMARY KEY AUTOINCREMENT,

waybillno VARCHAR(32) NOT NULL UNIQUE,

customerid INT NOT NULL,

status TINYINT NOT NULL DEFAULT 0,

CONSTRAINT chkwaybillno CHECK (waybillno REGEXP '^[A-Z]{2}[0-9]{12}$'),

CONSTRAINT chkstatus CHECK (status IN (0,1,2,3)),

CONSTRAINT fkcustomer FOREIGN KEY (customerid) REFERENCES customer(id)

就这么六行约束,把单号格式、状态枚举、客户关联全锁死了。后来他们的开发跟我说,上线之后数据质量问题直接降了百分之八十,以前每周都要跑脚本清理脏数据,现在几乎不用管了。Paragraph8 is just "CREATE TABLE waybill (" maybe need to keep as is but maybe need to adjust punctuation? It's fine.Paragraph9 etc.Paragraph7 ends with colon? Actually it's "当时我建表是这么写的:" then next paragraphs are code lines. That's okay.Paragraph8: 【第8段】CREATE TABLE waybill (Paragraph9: 【第9段】id INT PRIMARY KEY AUTOINCREMENT,Paragraph10: 【第10段】waybillno VARCHAR(32) NOT NULL UNIQUE,Paragraph11: 【第11段】customerid INT NOT NULL,Paragraph12: 【第12段】status TINYINT NOT NULL DEFAULT 0,Paragraph13: 【第13段】CONSTRAINT chkwaybillno CHECK (waybillno REGEXP '^[A-Z]{2}[0-9]{12}$'),Paragraph14: 【第14段】CONSTRAINT chkstatus CHECK (status IN (0,1,2,3)),Paragraph15: 【第15段】CONSTRAINT fkcustomer FOREIGN KEY (customerid) REFERENCES customer(id)Paragraph16: 【第16段】就这么六行约束,把单号格式、状态枚举、客户关联全锁死了。后来他们的开发跟我说,上线之后数据质量问题直接降了百分之八十,以前每周都要跑脚本清理脏数据,现在几乎不用管了。Paragraph17:

约束也不是越多越好,这玩意跟吃药一样,过量伤身。我见过有人为了保险,给每一列都加上唯一约束,结果业务上同一个客户确实可以下多笔订单,订单号可以唯一,但客户ID本身不可能唯一。这种过度设计不但没用,还会让插入性能大幅下降,因为每次插入都要检查好几个索引。所以约束的设计一定要基于真实业务规则,别拍脑袋。Check duplicates: "的"? Not. "了"? Not. "是"? Not.Paragraph18:

说个容易踩的坑——约束的命名。很多人写约束不指定名字,数据库自动生成一堆像“CONSTRAINT1”、“CONSTRAINT2”这种名字,等你想删除某个约束的时候,得先去查系统表才能找到它叫什么。所以建表的时候,请务必给每个约束起个能看懂的名字,格式建议用“约束类型表名字段名”,比如ukuseremail、ckorderstatus这样。等你维护半年这个库,你会感谢当初的自己。Check duplicates: maybe "的"? Not. "了"? Not. "是"? Not.Paragraph19:

说到底,数据库约束不是写几个关键字那么简单,它是你数据质量的一道防线。代码可能写错,接口可能被绕过,但约束只要写对了,垃圾数据就永远进不来。下次再有人问你“constraint数据库怎么用”,你就把这篇甩给他,然后补一句:“先想清楚你的业务规则,再动手写约束。”Check duplicates: maybe "的"? Not. "了"? Not. "是"? Not.We need to ensure no extra symbols, remove duplicate words like "的". I see some "的"? Not. There's "的" but not duplicate. There's "的" multiple times but not "的". There's "的" but not "的". There's "的" but okay.Check for "了": I don't see "了". There's "了" but not duplicate.Check for "是": not.Check for extra punctuation: maybe "——" dash is okay. There's "——". It's a special char but not prohibited? The requirement says remove abnormal symbols like乱码, special characters. The dash is a special character but maybe okay as it's a normal punctuation. Might be fine.But we might want to replace "——" with "—" or just "". It's a long dash. Could keep as "—". It's okay.Check for "的": Not present.Check for "了": Not present.Check for "是": Not present.Check for duplicate sentences: maybe "其实解决这个问题就一行SQL的事,在主键字段上再加个UNIQUE,或者干脆把订单号设计成业务主键,比如“20240615-0001”这种格式,再用数据库的唯一约束兜底,从根上杜绝重复。" That's unique.Check for duplicate paragraphs: none.Now we need to output with each paragraph starting with 【第X段】. Keep original numbering? Paragraphs are 1-19. We need to keep same numbering but after editing.We must keep code blocks as is? They are separate paragraphs with numbering. Keep them.Make sure no extra spaces or symbols.Let's rewrite each paragraph with smoother flow, removing redundant words.Paragraph1 edit: maybe remove "的" duplicate? Not needed. Keep as is but maybe adjust punctuation.Paragraph1: "前两天一个做后端的朋友跟我吐槽,说他们项目里数据乱得跟菜市场似的,用户表里居然能存负数年龄,订单表里的金额还能是空值。我问他建表的时候干嘛不加约束,他愣了半天反问我:“约束?那玩意儿不就是写几个关键字的事吗,加了有啥用?”这话我听了不下十遍,今天干脆把数据库约束这摊子事掰开揉碎了讲清楚,顺便给你几个能直接抄走的实战案例。"Seems fine.Paragraph2: "先搞清楚约束到底在防什么。数据库本质上就是个装数据的仓库,但你如果什么都不管往里塞,一个月后垃圾数据就能把你淹没。约束就是仓库门口的安检员,不合格的包裹直接拦下。最常见的五种约束包括:主键约束保证每一行都有唯一身份,外键约束管住表与表之间的关系,唯一约束防止重复数据,检查约束限定取值范围,非空约束拒绝空值。听着简单,但真正用对的人真不多。"Remove extra "的"? There's "的" but fine.Paragraph3: "我见过太多人把主键当摆设。比如一个电商项目,订单表主键用了自增ID,这本身没问题,但他们居然没加唯一约束,结果同一条订单因为代码 bug 被插入了两次,用户下单两件商品,后台却生成了四条记录。对账时,财务差点把开发骂哭。其实解决这个问题只要一行 SQL,在主键字段上再加个 UNIQUE,或者直接把订单号设计成业务主键,比如“20240615-0001”这种格式,再用数据库唯一约束兜底,从根上杜绝重复。"Paragraph4: "外键约束更是个又爱又恨的东西。爱它是因为能保证两张表的数据对得上,恨它是因为用不好会拖垮性能。我有个客户,他们的订单表和商品表做了外键关联,结果每次插入订单都要去校验商品是否存在,高峰期每秒上千并发,数据库直接被打爆。后来我们把外键校验挪到了应用层,数据库只保留索引,性能瞬间上去了。但得提醒你,外键约束不是不能用,而是要看场景。低频管理系统,外键能省掉大量代码逻辑;高并发核心链路,能不用就别用,出了事你兜不住。"Paragraph5: "检查约束是最被低估的一个。很多人不知道,MySQL 8.0 之前根本不支持 CHECK 约束,所以老项目里经常看到数据校验全靠代码写。但代码总有漏网之鱼。比如招聘系统,简历表里的期望薪资字段,前端明明做了校验,但有人直接调接口往数据库里塞了个负数,后端也没拦,结果候选人面试时 HR 看到的薪资是负的,场面一度尴尬。其实加一行 CONSTRAINT chksalary CHECK (expected_salary > 0),这类问题就不会发生。还有状态字段,比如订

推荐资讯

13261661949