在数据库设计与开发中,数据的准确性和一致性是核心要求。MySQL 约束(Constraint)作为数据库层面的 "数据规则",能直接限制表中数据的存储行为,从源头避免无效、重复或逻辑冲突的数据产生。本文将系统讲解 MySQL 中最常用的约束类型、操作语法、应用场景及注意事项,帮助你规范数据库设计,提升数据可靠性。
目录
[一、什么是 MySQL 约束?](#一、什么是 MySQL 约束?)
[二、MySQL 核心约束类型详解](#二、MySQL 核心约束类型详解)
[1. 主键约束(Primary Key)](#1. 主键约束(Primary Key))
[2. 自增长约束(Auto Increment)](#2. 自增长约束(Auto Increment))
[3. 外键约束(Foreign Key)](#3. 外键约束(Foreign Key))
[(1)准备父表(必须先有父表,且父表关联列需为主键 / 唯一键)](#(1)准备父表(必须先有父表,且父表关联列需为主键 / 唯一键))
[4. 唯一性约束(Unique)](#4. 唯一性约束(Unique))
[5. 非空约束(Not Null)](#5. 非空约束(Not Null))
[6. 一次性创建表并添加多约束(实战示例)](#6. 一次性创建表并添加多约束(实战示例))
[7. 查看表中所有约束](#7. 查看表中所有约束)
[五、 快速了解](#五、 快速了解)
一、什么是 MySQL 约束?
约束是 MySQL 中用于强制数据满足特定规则的数据库对象,它能在数据插入、修改、删除时自动校验,拒绝不符合规则的操作。
简单来说,约束就像数据库表的 "守门人",比如:
- 不允许重复的用户手机号(唯一性约束)
- 必须填写的用户姓名(非空约束)
- 订单表的用户 ID 必须对应存在的用户(外键约束)
相比于依赖应用程序逻辑校验,约束直接作用于数据库层面,不仅更高效,还能避免多应用操作数据库时出现的数据不一致问题。
二、MySQL 核心约束类型详解
1. 主键约束(Primary Key)
核心作用
- 唯一标识表中的每一行数据(数据不可重复)
- 主键列不允许为空(NULL)
- 一个表只能有一个主键(支持单列主键或多列联合主键)
常用操作
(1)创建表时添加主键
sql
-- 单列主键(最常用)
CREATE TABLE student (
st_id INT PRIMARY KEY, -- 直接在列后声明主键
st_name VARCHAR(20),
st_age INT
);
-- 联合主键(多列组合唯一标识,适用于无单一唯一列的场景)
CREATE TABLE score (
st_id INT,
subject_id INT,
score DOUBLE(5,2),
-- 两列组合作为主键,确保同一学生同一科目只有一条成绩记录
PRIMARY KEY (st_id, subject_id)
);
(2)修改表时添加主键
适用于已创建的表,需确保待设为主键的列无重复值且非空:
sql
-- 语法:ALTER TABLE 表名 ADD PRIMARY KEY(列名);
ALTER TABLE student ADD PRIMARY KEY(st_id);
(3)删除主键
删除主键时无需指定列名(一个表只有一个主键):
sql
-- 语法:ALTER TABLE 表名 DROP PRIMARY KEY;
ALTER TABLE student DROP PRIMARY KEY;
注意事项
- 主键列建议使用整数类型(INT/BIGINT),查询效率更高
- 联合主键中,只要任意一列的值不同,就视为不同记录
2. 自增长约束(Auto Increment)
核心作用
- 配合主键使用,自动为主键列生成递增的唯一值(无需手动插入)
- 自增长列必须是整数类型(INT、BIGINT 等)
- 默认从 1 开始,每次递增 1(可通过
AUTO_INCREMENT = n修改起始值)
常用操作
(1)创建表时设置自增长
sql
CREATE TABLE student (
st_id INT PRIMARY KEY AUTO_INCREMENT, -- 主键 + 自增长
st_name VARCHAR(20),
st_age INT
);
(2)修改表时添加自增长
需先将列设为主键或唯一键(自增长依赖唯一标识):
sql
-- 语法:ALTER TABLE 表名 MODIFY 列名 类型 AUTO_INCREMENT;
ALTER TABLE student MODIFY st_id INT AUTO_INCREMENT;
(3)删除自增长
只需去掉 AUTO_INCREMENT 关键字,保留列的原始类型:
sql
-- 语法:ALTER TABLE 表名 MODIFY 列名 类型;
ALTER TABLE student MODIFY st_id INT;
关键特性
- 自增长值一旦生成,删除数据后不会回滚(例如删除 ID=5 的记录,下次插入会从 6 开始)
- 可通过
ALTER TABLE student AUTO_INCREMENT = 100;手动设置自增长起始值(适用于需要特定 ID 段的场景)
3. 外键约束(Foreign Key)
核心作用
- 建立两个表之间的关联关系(父表和子表)
- 强制子表的外键值必须匹配父表的主键 / 唯一键值
- 保证数据的 "参照完整性",避免出现 "孤儿数据"(如不存在的班级 ID 对应学生)
核心概念
- 父表:被参照的表(如班级表
class) - 子表:使用外键的表(如学生表
student) - 外键列:子表中用于关联父表的列(如
student的cl_id)
常用操作
(1)准备父表(必须先有父表,且父表关联列需为主键 / 唯一键)
sql
-- 父表:班级表
CREATE TABLE class (
class_id INT PRIMARY KEY AUTO_INCREMENT,
class_name VARCHAR(20) NOT NULL,
class_teacher VARCHAR(20)
);
(2)创建子表时添加外键
sql
-- 子表:学生表
CREATE TABLE student (
st_id INT PRIMARY KEY AUTO_INCREMENT,
st_name VARCHAR(20) NOT NULL,
cl_id INT, -- 外键列,关联班级表的 class_id
-- 声明外键约束:约束名 + 外键列 + 参照表及列
CONSTRAINT fk_student_class FOREIGN KEY(cl_id) REFERENCES class(class_id)
);
(3)修改表时添加外键
sql
-- 步骤1:先给子表添加外键列(若未存在)
ALTER TABLE student ADD COLUMN cl_id INT;
-- 步骤2:添加外键约束
-- 语法:ALTER TABLE 子表名 ADD CONSTRAINT 约束名 FOREIGN KEY(子表列) REFERENCES 父表名(父表列);
ALTER TABLE student ADD CONSTRAINT fk_student_class FOREIGN KEY(cl_id) REFERENCES class(class_id);
(4)删除外键约束
删除外键需指定约束名(一个表可多个外键,需区分):
sql
-- 语法:ALTER TABLE 子表名 DROP FOREIGN KEY 约束名;
ALTER TABLE student DROP FOREIGN KEY fk_student_class;
进阶配置(解决外键关联删除问题)
默认情况下,父表数据被引用时无法删除。可通过以下配置优化:
sql
-- 级联删除:删除父表数据时,自动删除子表关联数据
ALTER TABLE student ADD CONSTRAINT fk_student_class
FOREIGN KEY(cl_id) REFERENCES class(class_id)
ON DELETE CASCADE;
-- 置空:删除父表数据时,子表外键列设为 NULL(需外键列允许为空)
ALTER TABLE student ADD CONSTRAINT fk_student_class
FOREIGN KEY(cl_id) REFERENCES class(class_id)
ON DELETE SET NULL;
注意事项
- 子表外键列的数据类型必须与父表关联列完全一致(如父表是 INT,子表不能是 VARCHAR)
- 父表的关联列必须是主键或唯一键
- 外键会增加表之间的耦合度,高并发场景下可考虑通过应用程序逻辑替代
4. 唯一性约束(Unique)
核心作用
- 保证列中数据不可重复
- 允许存在一个 NULL 值(与主键的核心区别)
- 一个表可以有多个唯一性约束(适用于多个需要去重的列)
常用操作
(1)创建表时添加唯一性约束
sql
CREATE TABLE student (
st_id INT PRIMARY KEY AUTO_INCREMENT,
st_name VARCHAR(20),
st_phone VARCHAR(11) UNIQUE, -- 手机号唯一
st_email VARCHAR(50) UNIQUE -- 邮箱唯一
);
(2)修改表时添加唯一性约束
sql
-- 语法:ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE(列名);
ALTER TABLE student ADD CONSTRAINT uk_student_name UNIQUE (st_name);
(3)删除唯一性约束
删除时使用 DROP KEY 而非 DROP UNIQUE:
sql
-- 语法:ALTER TABLE 表名 DROP KEY 约束名;
ALTER TABLE student DROP KEY uk_student_name;
与主键约束的区别
| 特性 | 主键约束 | 唯一性约束 |
|---|---|---|
| 允许为空 | ❌ 不允许 | ✅ 允许 1 个 NULL |
| 表中数量 | ❌ 只能 1 个 | ✅ 可以多个 |
| 自增长支持 | ✅ 支持 | ❌ 不支持 |
| 索引类型 | 聚集索引 | 非聚集索引 |
5. 非空约束(Not Null)
核心作用
- 强制列中数据不能为 NULL
- 插入或修改数据时,必须为该列赋值(否则报错)
常用操作
(1)创建表时添加非空约束
sql
CREATE TABLE student (
st_id INT PRIMARY KEY AUTO_INCREMENT,
st_name VARCHAR(20) NOT NULL, -- 姓名必须填写
st_grade DOUBLE(5,2) NOT NULL DEFAULT 0.00 -- 成绩非空,默认值0.00
);
(2)修改表时添加非空约束
sql
-- 语法:ALTER TABLE 表名 MODIFY 列名 类型 NOT NULL;
ALTER TABLE student MODIFY st_grade DOUBLE(5,2) NOT NULL;
(3)删除非空约束
显式声明 NULL 即可(MySQL 中列默认允许为空):
sql
-- 语法:ALTER TABLE 表名 MODIFY 列名 类型 NULL;
ALTER TABLE student MODIFY st_grade DOUBLE(5,2) NULL;
注意事项
- 非空约束可与
DEFAULT配合使用(如上述成绩默认 0.00),避免插入时未赋值报错 - 若列同时设置非空和默认值,插入时不指定该列,会自动填充默认值
6. 一次性创建表并添加多约束(实战示例)
实际开发中,通常在创建表时就定义好所有约束,示例如下:
sql
-- 部门表(父表)
CREATE TABLE depts (
dept_id INT PRIMARY KEY AUTO_INCREMENT, -- 主键+自增长
dept_name VARCHAR(20) UNIQUE NOT NULL, -- 部门名称唯一+非空
location VARCHAR(50) NOT NULL DEFAULT '未知' -- 地点非空,默认值
);
-- 员工表(子表)
CREATE TABLE emp (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20) NOT NULL,
dept_id INT,
phone VARCHAR(11) UNIQUE,
salary DECIMAL(10,2) NOT NULL DEFAULT 3000.00,
-- 外键约束:关联部门表
CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id)
REFERENCES depts(dept_id)
ON DELETE SET NULL -- 删除部门时,员工的部门ID置空
);
7. 查看表中所有约束
若需确认表已添加的约束信息,可使用以下命令:
sql
-- 语法:SHOW KEYS FROM 表名; 或 SHOW INDEX FROM 表名;
SHOW KEYS FROM student;
SHOW INDEX FROM emp;
关键结果列说明
Key_name:约束名称(主键约束固定为PRIMARY)Column_name:约束对应的列名Non_unique:0 表示唯一约束(主键、Unique),1 表示非唯一Constraint_type:约束类型(PRIMARY KEY、UNIQUE、FOREIGN KEY 等)
三、约束应用场景速查表
| 约束类型 | 核心作用 | 典型应用场景 |
|---|---|---|
| 主键 | 唯一标识行数据 | 用户 ID、订单 ID、学生 ID |
| 自增长 | 自动生成主键值 | 无需手动维护的 ID 列 |
| 外键 | 表间关联,保证参照完整性 | 学生 - 班级、员工 - 部门、订单 - 用户 |
| 唯一性 | 列数据去重 | 手机号、邮箱、用户名 |
| 非空 | 强制必须填写 | 姓名、身份证号、联系方式 |
四、使用约束的最佳实践
- 优先在创建表时定义约束:避免后续修改表结构导致的数据不一致
- 合理命名约束 :采用 "约束类型_表名_列名" 格式(如
fk_emp_dept),便于维护 - 避免过度使用约束:约束会增加数据操作的校验开销,非必要场景可简化
- 外键谨慎使用:高并发、大数据量场景下,外键可能影响性能,可通过应用程序保证数据一致性
- 结合默认值使用 :非空约束搭配默认值(如
NOT NULL DEFAULT 0),提升用户体验
五、 快速了解
主键
添加主键约束
alter table 表名 add primary key(列名);
alter table student add primary key(st_id);
主键自增长
alter table 表名 modify 列名 类型 auto_increment;
alter table student modify st_id int auto_increment;
删除主键
alter table 表名 drop primary key;
alter table studnet drop primary key;
删除主键自增长
alter table 表名 modify 列名 类型;
alter table studnent modify st_id int;
外键
添加外键约束
alter table 表名 add constraint 约束名 foreign key(列名) references 参照的表名(参照的列名);
create table class (class_id int,class_name varchar(20),class_teacher varchar(20));
alter table class add primary key(class_id);
alter table class modify class_id int auro_increment;
alter table student add column cl_id int;
alter table student constraint st_fk foreign key(cl_id) references class(class_id);
删除外键约束
alter table 表名 drop foreign key 约束名;
alter table student drop foreign key st_fk;
添加唯一性约束
alter table 表名 add constraint 约束名 unique(列名)
alter table student add constraint st_uk nuique (st_name);
删除唯一性约束
alter table 表名 drop key 约束名;
alter table student drop key st_uk;
添加非空约束
alter table 表名 modify 列名 类型 not null;
alter table student modify st_grade double(5,2) not null;
删除非空约束
alter table 表名 modify 列名 类型 null;
alter table student modify st_grade double(5,2) null;
创建表时添加约束
create table depts (depts_id int primary key auto_increment,depts_name varchar(20) unique , location_id int not null;
展示表中的约束信息
show keys from 表名;
show keys from student;
总结
- MySQL 约束是保障数据完整性的核心机制,常用类型包括主键、自增长、外键、唯一性、非空;
- 每种约束都有明确的应用场景(如唯一标识用主键、表间关联用外键),需根据业务需求选择;
- 约束操作的核心语法需牢记(如添加主键用
ADD PRIMARY KEY,删除外键用DROP FOREIGN KEY),同时注意数据类型匹配、约束依赖关系等细节。
掌握约束的使用,能让你的数据库设计更规范、数据更可靠,是后端开发必备的基础技能。实际开发中,需结合业务场景灵活运用,在数据安全性和性能之间找到平衡~
希望这篇文章对你有帮助,如果你有任何问题或建议,欢迎在评论区留言。谢谢阅读(求攒攒 收藏 关注)!
