【MySQL】04.约束
目录
学习 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 行为];
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)