MySQL 约束详解:保证数据完整性的核心机制

在数据库设计与开发中,数据的准确性和一致性是核心要求。MySQL 约束(Constraint)作为数据库层面的 "数据规则",能直接限制表中数据的存储行为,从源头避免无效、重复或逻辑冲突的数据产生。本文将系统讲解 MySQL 中最常用的约束类型、操作语法、应用场景及注意事项,帮助你规范数据库设计,提升数据可靠性。


目录

[一、什么是 MySQL 约束?](#一、什么是 MySQL 约束?)

[二、MySQL 核心约束类型详解](#二、MySQL 核心约束类型详解)

[1. 主键约束(Primary Key)](#1. 主键约束(Primary Key))

核心作用

常用操作

(1)创建表时添加主键

(2)修改表时添加主键

(3)删除主键

注意事项

[2. 自增长约束(Auto Increment)](#2. 自增长约束(Auto Increment))

核心作用

常用操作

(1)创建表时设置自增长

(2)修改表时添加自增长

(3)删除自增长

关键特性

[3. 外键约束(Foreign Key)](#3. 外键约束(Foreign Key))

核心作用

核心概念

常用操作

[(1)准备父表(必须先有父表,且父表关联列需为主键 / 唯一键)](#(1)准备父表(必须先有父表,且父表关联列需为主键 / 唯一键))

(2)创建子表时添加外键

(3)修改表时添加外键

(4)删除外键约束

进阶配置(解决外键关联删除问题)

注意事项

[4. 唯一性约束(Unique)](#4. 唯一性约束(Unique))

核心作用

常用操作

(1)创建表时添加唯一性约束

(2)修改表时添加唯一性约束

(3)删除唯一性约束

与主键约束的区别

[5. 非空约束(Not Null)](#5. 非空约束(Not Null))

核心作用

常用操作

(1)创建表时添加非空约束

(2)修改表时添加非空约束

(3)删除非空约束

注意事项

[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
  • 外键列:子表中用于关联父表的列(如 studentcl_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 列
外键 表间关联,保证参照完整性 学生 - 班级、员工 - 部门、订单 - 用户
唯一性 列数据去重 手机号、邮箱、用户名
非空 强制必须填写 姓名、身份证号、联系方式

四、使用约束的最佳实践

  1. 优先在创建表时定义约束:避免后续修改表结构导致的数据不一致
  2. 合理命名约束 :采用 "约束类型_表名_列名" 格式(如 fk_emp_dept),便于维护
  3. 避免过度使用约束:约束会增加数据操作的校验开销,非必要场景可简化
  4. 外键谨慎使用:高并发、大数据量场景下,外键可能影响性能,可通过应用程序保证数据一致性
  5. 结合默认值使用 :非空约束搭配默认值(如 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;

总结

  1. MySQL 约束是保障数据完整性的核心机制,常用类型包括主键、自增长、外键、唯一性、非空;
  2. 每种约束都有明确的应用场景(如唯一标识用主键、表间关联用外键),需根据业务需求选择;
  3. 约束操作的核心语法需牢记(如添加主键用 ADD PRIMARY KEY,删除外键用 DROP FOREIGN KEY),同时注意数据类型匹配、约束依赖关系等细节。

掌握约束的使用,能让你的数据库设计更规范、数据更可靠,是后端开发必备的基础技能。实际开发中,需结合业务场景灵活运用,在数据安全性和性能之间找到平衡~

希望这篇文章对你有帮助,如果你有任何问题或建议,欢迎在评论区留言。谢谢阅读(求攒攒 收藏 关注)!

相关推荐
九千七52642 分钟前
sklearn学习(5)线性回归和逻辑回归
人工智能·学习·机器学习·逻辑回归·线性回归·sklearn
职业码农NO.142 分钟前
架构模型:企业架构、技术架构、C4模型、TOGAF、互联网模型优缺点分析与学习
学习·架构·系统架构·软件工程
摇滚侠44 分钟前
零基础小白自学 Git_Github 教程,Action CI/CD 完整实践,笔记23
笔记·git·ci/cd
走在路上的菜鸟1 小时前
Android学Dart学习笔记第九节 Patterns
android·笔记·学习·flutter
伐尘1 小时前
【MySQL】windows系统下mysql慢日志查询
windows·mysql·adb
理想三旬1 小时前
数据定义:模式、表、索引
数据库
c***87191 小时前
讲解进阶之路:模块、包和异常处理-上篇
数据库·redis·哈希算法
代码游侠1 小时前
学习笔记——栈
开发语言·数据结构·笔记·学习·算法
!chen1 小时前
Oracle分区表+本地索引 核心优化方案
数据库·oracle