MySQL约束全攻略 🛡️
🛡️ 数据卫士训练营
在这里你将认识六大守护神:
- 主键约束 → 数据身份证 🆔
- 外键约束 → 关系红娘 💞
- 唯一约束 → 防重复卫士 🚫
- 非空约束 → 必填项监工 📝
- 默认约束 → 贴心小助手 🤖
- 检查约束 → 数据质检员 🔍
1. 主键约束(PRIMARY KEY)🆔
🎯 主键三原则
- 唯一性:全表唯一,像身份证号
- 非空性:必须填写,不能为NULL
- 简洁性:推荐使用自增整数
sql
-- 创建带主键的用户表
CREATE TABLE 用户 (
用户ID INT PRIMARY KEY AUTO_INCREMENT,
用户名 VARCHAR(20) NOT NULL
);
-- 联合主键示例(订单明细)
CREATE TABLE 订单明细 (
订单ID INT,
商品ID INT,
数量 INT,
PRIMARY KEY (订单ID, 商品ID)
);🚨 主键翻车现场:
sql
-- 错误:主键重复
INSERT INTO 用户 VALUES (1, '张三'), (1, '李四'); ❌
-- 错误:主键为NULL
INSERT INTO 用户 (用户名) VALUES ('王五'); ❌2. 外键约束(FOREIGN KEY)💞
⚡ 关系数据库的灵魂
sql
-- 部门表(主表)
CREATE TABLE 部门 (
部门ID INT PRIMARY KEY,
名称 VARCHAR(20)
);
-- 员工表(从表)
CREATE TABLE 员工 (
员工ID INT PRIMARY KEY,
姓名 VARCHAR(20),
部门ID INT,
FOREIGN KEY (部门ID) REFERENCES 部门(部门ID)
);外键恋爱法则 💑
- 主表要先存在(先有部门才能招人)
- 插入从表数据时,外键值必须存在于主表
- 删除主表记录前,要先处理从表相关数据
sql
-- 添加外键约束(带级联删除)
ALTER TABLE 员工
ADD CONSTRAINT fk_部门
FOREIGN KEY (部门ID)
REFERENCES 部门(部门ID)
ON DELETE CASCADE;3. 唯一约束(UNIQUE)🚫
🎭 防重复小能手
sql
CREATE TABLE 学生 (
学号 INT PRIMARY KEY,
身份证号 CHAR(18) UNIQUE, -- 唯一约束
邮箱 VARCHAR(50) UNIQUE
);🔍 唯一 vs 主键:
| 特性 | 主键约束 | 唯一约束 |
|---|---|---|
| 唯一性 | ✅ | ✅ |
| 非空性 | ✅ | ❌ |
| 数量限制 | 1个/表 | 多个/表 |
4. 非空约束(NOT NULL)📝
sql
CREATE TABLE 图书 (
书号 INT PRIMARY KEY,
书名 VARCHAR(100) NOT NULL, -- 必须填写
作者 VARCHAR(50) NOT NULL,
出版日期 DATE
);🚨 空值陷阱:
sql
-- 错误:书名未填写
INSERT INTO 图书 (书号, 作者) VALUES (1001, '张三'); ❌
-- 正确:所有NOT NULL字段都要赋值
INSERT INTO 图书 VALUES (1001, 'MySQL指南', '李四', '2023-01-01'); ✅5. 默认约束(DEFAULT)🤖
🤖 智能填充助手
sql
CREATE TABLE 订单 (
订单ID INT PRIMARY KEY,
下单时间 DATETIME DEFAULT CURRENT_TIMESTAMP, -- 自动记录时间
状态 ENUM('待付款', '已发货', '已完成') DEFAULT '待付款',
支付方式 VARCHAR(20) DEFAULT '支付宝'
);6. 检查约束(CHECK)🔍
🧪 数据质检员
sql
-- 年龄必须大于18岁
CREATE TABLE 会员 (
会员ID INT PRIMARY KEY,
姓名 VARCHAR(20),
年龄 INT CHECK (年龄 >= 18)
);
-- 价格必须为正数
CREATE TABLE 商品 (
商品ID INT PRIMARY KEY,
价格 DECIMAL(10,2) CHECK (价格 > 0)
);综合实战:电商系统约束设计 🛒
sql
CREATE TABLE 用户 (
用户ID INT AUTO_INCREMENT PRIMARY KEY,
用户名 VARCHAR(20) NOT NULL UNIQUE,
密码 VARCHAR(100) NOT NULL,
注册时间 DATETIME DEFAULT CURRENT_TIMESTAMP,
邮箱 VARCHAR(50) UNIQUE CHECK (邮箱 LIKE '%@%')
);
CREATE TABLE 订单 (
订单ID BIGINT PRIMARY KEY,
用户ID INT,
总金额 DECIMAL(10,2) CHECK (总金额 >= 0),
状态 ENUM('待支付', '已发货', '已完成') DEFAULT '待支付',
FOREIGN KEY (用户ID) REFERENCES 用户(用户ID)
);🚨 约束使用红宝书
- 主键要简洁:避免使用业务字段
- 外键要谨慎:影响性能,大系统慎用
- 检查约束要全面:如邮箱格式、价格范围
- 默认值要合理:根据业务需求设置
- 联合唯一:多个字段组合唯一
🎁 高级技巧
sql
-- 添加表级约束
ALTER TABLE 员工
ADD CONSTRAINT chk_年龄
CHECK (年龄 BETWEEN 18 AND 60);
-- 删除约束
ALTER TABLE 商品
DROP CHECK chk_价格;
-- 禁用外键检查(数据迁移时使用)
SET FOREIGN_KEY_CHECKS = 0;
-- 恢复检查
SET FOREIGN_KEY_CHECKS = 1;📜 约束顺口溜
主键唯一又非空,数据身份它掌控
外键维系表关系,删除更新要慎重
唯一约束防重复,空值除外可宽容
非空字段必须填,默认值来帮大忙
检查约束保质量,数据规则不放松