1. 数据库约束的本质与价值
刚入行那会儿,我最头疼的就是处理脏数据——用户表里重复的邮箱、订单表中不存在的商品ID、员工信息里空缺的身份证号。直到系统上线后频繁出现"Unknown column"错误,才真正明白约束(Constraints)不是限制自由的枷锁,而是保障数据质量的基石。
约束的本质是预定义的校验规则,在SQL层面对数据完整性进行强制保护。与应用程序中的校验逻辑不同,它具备三个核心特性:
- 声明式定义:通过DDL语句在表结构中声明,与业务代码解耦
- 原子性校验:在事务提交前完成检查,避免中间状态污染
- 优化器可见:数据库引擎可利用约束信息优化查询计划
以电商系统为例,没有约束的订单表可能出现:
- 订单金额为负数(财务漏洞)
- 买家ID指向不存在的用户(关联断裂)
- 同一订单号重复出现(业务混乱)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 五大约束类型详解
2.1 NOT NULL:空值防御者
sql复制CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
social_id CHAR(18) NOT NULL
);
典型场景:
- 用户注册时必填字段(用户名/手机号)
- 金融系统中的金额字段
- 业务流程中的状态标识字段
避坑指南:
- 与DEFAULT的配合:
NOT NULL DEFAULT ''比纯NOT NULL更友好 - 性能影响:NOT NULL列通常比可为NULL的列占用更少存储空间
- 索引优化:对NOT NULL列建索引时考虑使用
NOT NULL索引
警告:修改已有列为NOT NULL时,必须确保该列不存在NULL值,否则会执行失败。建议先用
UPDATE table SET column=default_value WHERE column IS NULL预处理。
2.2 UNIQUE:数据指纹校验
sql复制CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE,
phone CHAR(11) UNIQUE
);
实现原理:
数据库通过隐式创建唯一索引来实现UNIQUE约束。以InnoDB为例,会在information_schema.STATISTICS中生成对应的BTREE索引。
复合唯一键示例:
sql复制CREATE TABLE class_schedule (
class_id INT,
week_day TINYINT,
start_time TIME
