学习 MySQL 的“约束(Constraints)”是掌握数据库设计的核心步骤。
约束其实就是数据库的“交通规则”——它们是强制规定在表中的数据规则,用来保证数据的准确性可靠性(也就是我们常说的“数据完整性”)。

如果不小心违反了这些规则,MySQL 就会报错并拒绝你的操作。

MySQL 中最常用的约束主要有 7 种。


1. 主键约束 (PRIMARY KEY)

作用:唯一标识表中的每一条记录。它自带两个属性:不能重复(唯一)不能为空(NOT NULL)。一张表只能有一个主键(但可以由多个列组合成复合主键)。
日常场景:身份证号、学号、订单号。

CREATE TABLE Students (
    id INT PRIMARY KEY,      -- 这里设置了主键
    name VARCHAR(50)
);

-- 报错情况:
-- INSERT INTO Students (id, name) VALUES (1, '张三'); 
-- 如果再执行一次上面的代码,会报错,因为 id 为 1 的记录已经存在了。

2. 自增约束 (AUTO_INCREMENT)

作用:每次插入新记录时,该字段的值会自动增加(默认每次加 1)。通常和主键搭配使用,这样你就不需要手动去生成唯一的 ID 了。

CREATE TABLE Users (
    user_id INT PRIMARY KEY AUTO_INCREMENT, -- 主键且自动递增
    username VARCHAR(50)
);

-- 正确操作:不需要管 user_id,它会自动变成 1, 2, 3...
INSERT INTO Users (username) VALUES ('Alice');
INSERT INTO Users (username) VALUES ('Bob');

3. 非空约束 (NOT NULL)

作用:限制该字段的值绝对不能为 NULL(空值)。即插入数据时,必须给这个字段填上内容。
日常场景:注册账号时的“必填项”,比如密码。

CREATE TABLE Accounts (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,  -- 必须填用户名
    password VARCHAR(50) NOT NULL   -- 必须填密码
);

-- 报错情况:
-- INSERT INTO Accounts (username) VALUES ('admin'); 
-- 报错,因为 password 字段没有给值,且它不允许为空。

4. 唯一约束 (UNIQUE)

作用:保证该字段的所有值都是互不相同的。
注意点:与主键不同的是,一张表可以有多个 UNIQUE 约束,而且 UNIQUE 字段允许为 NULL(在 MySQL 中,可以有多个 NULL 值,因为 NULL 和 NULL 是不相等的)。
日常场景:邮箱地址、手机号码。

CREATE TABLE Employees (
    emp_id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(100) UNIQUE,  -- 邮箱不能和别人重复
    phone VARCHAR(20) UNIQUE    -- 手机号不能重复
);

5. 默认值约束 (DEFAULT)

作用:如果在插入数据时没有给这个字段赋值,MySQL 会自动填入你预设的“默认值”。
日常场景:用户的默认头像、账号的默认状态(比如“正常”)。

CREATE TABLE Articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(100) NOT NULL,
    status VARCHAR(20) DEFAULT 'Draft' -- 如果不传状态,默认就是草稿 (Draft)
);

-- 正确操作:
INSERT INTO Articles (title) VALUES ('学习MySQL的第一天');
-- 此时这条数据的 status 会自动变成 'Draft'。

6. 检查约束 (CHECK)

作用:保证字段的值符合指定的条件表达式。(注:MySQL 8.0.16 之后才真正完美支持 CHECK 约束,之前的版本写了也不生效
日常场景:年龄必须大于 0 且小于 150;性别只能是男或女。

CREATE TABLE Persons (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT CHECK (age >= 18) -- 年龄必须大于等于18岁
);

-- 报错情况:
-- INSERT INTO Persons (name, age) VALUES ('未成年', 16);
-- 报错,因为违反了 CHECK 约束 (16 不满足 >= 18)。

7. 外键约束 (FOREIGN KEY)

收到!刚才我们聊了“为什么不用”的架构思想,现在我们回归技术本身,把外键约束的语法、操作以及那 5 种处理行为彻底讲透。这部分是面试和实操中的重头戏。

添加外键有两种时机:建表时直接搞定,或者表建好后再追加。

1. 建表时添加

在创建子表(从表)的最后,指定外键规则。

CREATE TABLE emp (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    dept_id INT, -- 这个是要关联外键的字段
    -- [CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名)
    CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id)
);
2. 后期追加(ALTER TABLE)

如果表已经存在,使用 ALTER 命令。这是最常用的方式。

ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id);
3.删除外键约束

注意:删除外键时,使用的是外键的名称(fk_xxx),而不是字段名。

ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept_id;
4. 核心重点:删除/更新行为

当父表(主表)的数据被删掉或改掉时,子表(从表)该怎么办?MySQL 提供了 5 种“态度”。

行为名称 行为说明 形象理解
NO ACTION 检查是否有对应外键,如果有则不允许父表操作。 拒之门外:只要还有兵,就不准撤掉将军。
RESTRICT 与 NO ACTION 一致,MySQL 的默认行为。 同上
CASCADE 父表删除/更新,子表跟着删除/更新。 连坐制度:将军撤了,底下的兵全部解散。
SET NULL 父表删除/更新,子表对应外键设为 NULL。 恢复自由身:将军撤了,兵留着,但暂时没长官了。
SET DEFAULT 父表变更,子表设为默认值。 归队:将军撤了,兵自动归入预备役。(InnoDB不支持)

像下面这样加,ON UPDTE指的是更新时候,ON DELETE则是删除的时候的行为。

ALTER TABLE 表名 ADD CONSTRAINT 外键名 
FOREIGN KEY (外键字段) REFERENCES 主表(主表字段) 
[ON UPDATE 行为] [ON DELETE 行为];
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐