Skip to content

MySQL约束全攻略 🛡️

🛡️ 数据卫士训练营

在这里你将认识六大守护神:

  1. 主键约束 → 数据身份证 🆔
  2. 外键约束 → 关系红娘 💞
  3. 唯一约束 → 防重复卫士 🚫
  4. 非空约束 → 必填项监工 📝
  5. 默认约束 → 贴心小助手 🤖
  6. 检查约束 → 数据质检员 🔍

1. 主键约束(PRIMARY KEY)🆔

🎯 主键三原则

  1. 唯一性:全表唯一,像身份证号
  2. 非空性:必须填写,不能为NULL
  3. 简洁性:推荐使用自增整数
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)
);

外键恋爱法则 💑

  1. 主表要先存在(先有部门才能招人)
  2. 插入从表数据时,外键值必须存在于主表
  3. 删除主表记录前,要先处理从表相关数据
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)
);

🚨 约束使用红宝书

  1. 主键要简洁:避免使用业务字段
  2. 外键要谨慎:影响性能,大系统慎用
  3. 检查约束要全面:如邮箱格式、价格范围
  4. 默认值要合理:根据业务需求设置
  5. 联合唯一:多个字段组合唯一

🎁 高级技巧

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;

📜 约束顺口溜

主键唯一又非空,数据身份它掌控
外键维系表关系,删除更新要慎重
唯一约束防重复,空值除外可宽容
非空字段必须填,默认值来帮大忙
检查约束保质量,数据规则不放松