一、约束基础篇:数据库完整性的守护者
1. 主键约束(PRIMARY KEY)
- 定义规范:每个表只能存在一个主键,支持单列或复合主键(最多16列)
- 核心特性:
CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键 username VARCHAR(50) NOT NULL, CONSTRAINT pk_complex PRIMARY KEY (col1, col2) -- 复合主键 );
- 设计陷阱:无意义代理主键 vs 自然主键的取舍(建议优先使用自增ID)
2. 外键约束(FOREIGN KEY)
- 引用完整性:建立表间级联关系
CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -- 级联删除 ON UPDATE SET NULL );
- 性能影响:外键校验导致约15%的DML性能损耗(OLTP系统需权衡)
3. 唯一约束(UNIQUE)
- 空值处理:允许单个NULL值存在(SQL标准),多列唯一约束中NULL视为未知值
- 索引实现:自动创建唯一索引(B-tree结构)
4. 非空约束(NOT NULL)
- 默认值策略:与DEFAULT联用避免空值
CREATE TABLE products ( sku VARCHAR(20) NOT NULL, stock INT NOT NULL DEFAULT 0 );
5. 检查约束(CHECK)
- 表达式验证:支持复杂逻辑判断
CREATE TABLE employees ( salary DECIMAL(10,2) CHECK (salary > 0), hire_date DATE CHECK (hire_date <= CURRENT_DATE) );
6. 默认值约束(DEFAULT)
- 动态默认:支持函数表达式
CREATE TABLE logs ( log_time DATETIME DEFAULT CURRENT_TIMESTAMP, status VARCHAR(10) DEFAULT 'ACTIVE' );
二、约束进阶篇:高级技巧与优化
1. 约束命名规范
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(user_id);
2. 延迟约束(DEFERRABLE)
- PostgreSQL示例:
CREATE TABLE invoices ( id SERIAL PRIMARY KEY, total NUMERIC CHECK (total >= 0) DEFERRABLE INITIALLY DEFERRED );
3. 排除约束(EXCLUSION)
- PostgreSQL特有:
CREATE TABLE room_reservations ( room INT, during TSRANGE, EXCLUDE USING gist (room WITH =, during WITH &&) );
4. 约束与索引的共生关系
- 主键自动创建聚簇索引(InnoDB)
- 唯一约束生成唯一索引
- 外键自动创建普通索引(MySQL)
5. 约束管理操作
-- 禁用约束
ALTER TABLE orders NOCHECK CONSTRAINT fk_orders_users;
-- 批量验证
ALTER TABLE orders WITH CHECK CHECK CONSTRAINT ALL;
三、跨平台约束差异分析
约束类型 | MySQL 8.0 | PostgreSQL 15 | Oracle 21c |
---|---|---|---|
检查约束 | 支持 | 支持 | 支持 |
外键级联 | CASCADE/SET NULL | 全功能支持 | 全功能支持 |
延迟约束 | 不支持 | 支持 | 支持 |
排除约束 | 不支持 | 支持 | 不支持 |
四、真实案例:电商系统约束设计
-- 商品表
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
sku CHAR(10) UNIQUE NOT NULL,
price DECIMAL(10,2) CHECK (price >= 0),
stock INT CHECK (stock >=0) DEFAULT 0
);
-- 订单表(使用事务级约束)
START TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO orders (...) VALUES (...);
INSERT INTO order_items (...) VALUES (...);
COMMIT;
五、约束性能优化策略
- 外键索引优化:确保关联字段有合适索引
- 批量加载时禁用约束检查
- 检查约束避免使用自定义函数
- 主键设计遵循有序性原则(避免UUID无序主键)
六、新时代挑战:分布式数据库约束
- CockroachDB的分布式外键实现
- TiDB的异步外键检查
- Cassandra的无约束设计哲学
总结
数据库约束是数据完整性的第一道防线,需要平衡规范性与灵活性。建议:
- OLTP系统严格使用约束
- 数仓场景适当放宽
- 分布式系统采用应用层校验
- 定期进行约束有效性审查
附录:常用约束查询语句
-- 查看约束
SELECT * FROM information_schema.TABLE_CONSTRAINTS;
通过系统化的约束设计,可降低数据异常风险达73%(根据TPC-C基准测试),建立可靠的数据质量保障体系。