MySQL约束

1838 字
9 分钟
MySQL约束

约束(Constraint)是作用于数据表列 / 表级别的强制规则,用于限制写入表中的数据格式、范围、关联关系,从数据库底层保障数据的准确性、完整性、一致性,是关系型数据库数据治理的核心能力。

NOT NULL 非空约束#

强制字段不能存储 NULL 值,插入 / 更新数据时,该字段必须填写有效值,否则 SQL 执行报错。

  • NULL ≠ 空字符串 ”、0:MySQL 中,NULL 代表 “未知值”,和空字符串、数字 0 是完全不同的概念,非空约束仅禁止 NULL,允许空字符串、0 写入。
  • NOT NULL 常和 DEFAULT 配合使用:如果字段设置了 NOT NULL 但无 DEFAULT,插入时不赋值会直接报错;搭配 DEFAULT 后,未赋值时自动填充默认值,避免报错。
  • 主键字段默认自带 NOT NULL:无需额外声明,主键字段强制非空。
  • 仅支持列级约束:不能在表级声明 NOT NULL 约束。

DEFAULT 默认值约束#

给字段设置默认值,当插入新记录时,若未给该字段赋值,自动使用默认值填充,避免出现 NULL 值,简化 SQL 编写。

  • 版本兼容问题:MySQL 5.6 及之前,只有 TIMESTAMP 类型支持 DEFAULT CURRENT_TIMESTAMP;MySQL 5.6+ 开始,DATETIME 类型也支持默认值为当前时间。
  • 默认值仅在 “未赋值” 时生效:如果插入时显式给字段赋值为 NULL,即使有 DEFAULT,也会写入 NULL(若字段无 NOT NULL 约束)。
  • 默认值必须匹配字段类型:比如 INT 类型字段不能设置字符串默认值,否则会报错。

UNIQUE 唯一约束#

保证字段(或字段组合)中的所有值都是唯一的,不允许出现重复值,用于避免业务上的重复数据。

  • UNIQUE 允许 NULL 值:MySQL 中,NULL 不等于任何值(包括自己),所以唯一约束的字段允许多个 NULL 值写入,不会触发重复报错,这是和主键的核心区别之一。
  • 一个表可以有多个 UNIQUE 约束:而主键一个表只能有一个。
  • 复合唯一约束:多个字段的组合值唯一,单个字段可以重复,只要组合不重复即可,比如用户表中 “用户名 + 租户 ID” 复合唯一,不同租户可以有相同用户名。
  • 唯一约束会自动创建唯一索引:数据库会给 UNIQUE 字段自动创建唯一索引,提升查询效率,同时通过索引保证唯一性。

PRIMARY KEY 主键约束#

主键约束是 NOT NULL + UNIQUE 的组合,唯一标识表中的每一行记录,是表中记录的 “身份证号”,一个表只能有一个主键(可以是单个字段,也可以是多个字段组成的复合主键)。

  • 主键强制非空 + 唯一:主键字段不允许 NULL 值,不允许重复值,无需额外声明 NOT NULL。
  • 一个表只能有一个主键:即使是复合主键,也是一个主键,由多个字段组成。
  • 主键推荐使用无业务含义的自增 ID:比如 INT/BIGINT 类型的 AUTO_INCREMENT 字段,避免使用业务字段(如身份证号、学号)作为主键,业务字段一旦变更,会引发外键、索引的连锁问题。
  • 主键会自动创建聚簇索引:InnoDB 存储引擎中,表的数据是按主键的聚簇索引组织的,主键查询性能是最高的。
  • AUTO_INCREMENT 只能用于主键 / 唯一键字段:普通字段无法设置自增属性。

主键 vs 唯一约束核心区别:

特性PRIMARY KEYUNIQUE
非空限制强制非空,不允许 NULL允许 NULL 值,且可多个 NULL
数量限制一个表只能有 1 个一个表可以有多个
索引类型自动创建聚簇索引自动创建唯一二级索引
自增属性可搭配 AUTO_INCREMENT仅唯一键字段可搭配,极少用
核心用途唯一标识一行记录避免业务字段重复

CHECK 检查约束#

限制字段的值必须满足指定的布尔条件,只有条件为 TRUE 的数据才能写入,否则 SQL 执行报错,用于实现业务自定义的规则校验。

  • 版本重大差异:MySQL 8.0.16 版本之前,虽然语法上支持 CHECK 约束,但数据库会忽略该约束,不会生效;8.0.16 及以上版本才真正实现了 CHECK 约束的完整功能,5.7 及以下版本无法使用。
  • 检查条件必须返回布尔值:可以使用比较运算符、逻辑运算符、IN、BETWEEN、LIKE 等,条件为 FALSE 时拒绝写入,UNKNOWN(比如 NULL 值参与运算)时不拒绝。
  • 多字段关联校验:表级 CHECK 约束可以实现多个字段的关联校验,比如 “订单结束时间必须晚于开始时间”、“折扣价必须低于原价”。

FOREIGN KEY 外键约束#

外键约束用于建立和强制两个表之间的关联关系,外键字段在从表(子表)中,关联主表(父表)的主键 / 唯一键字段,保证从表的外键值必须在主表的关联字段中存在,避免 “脏数据”,保障参照完整性。

级联动作详解(ON DELETE / ON UPDATE):级联动作定义了主表的记录被删除 / 更新时,从表关联数据的处理规则,是外键约束的核心配置,常用选项如下:

级联选项核心作用使用场景
RESTRICT(默认值)主表删除 / 更新时,若从表有关联数据,直接拒绝操作核心基础数据,不允许随意删除,比如班级、商品分类
CASCADE主表删除 / 更新时,从表关联数据同步删除 / 更新父子强关联数据,比如用户删除,对应的收货地址、订单也删除
SET NULL主表删除 / 更新时,从表关联的外键字段设置为 NULL(要求外键字段允许 NULL)可选关联数据,比如员工所属部门删除,员工的部门 ID 置空
NO ACTION和 RESTRICT 完全一致,MySQL 中无区别,是 SQL 标准的语法无特殊场景,兼容 SQL 标准
  • 存储引擎限制:只有 InnoDB 存储引擎支持外键约束,MyISAM 引擎不支持,这是最常见的新手踩坑点。
  • 关联字段要求:主表的关联字段必须是主键或唯一键;从表的外键字段和主表的关联字段,数据类型、长度、字符集必须完全一致,否则无法创建外键。
  • 外键字段可以重复、可以为 NULL:除非额外设置了 NOT NULL、UNIQUE 约束,外键本身不限制重复和 NULL。
  • 数据写入顺序:必须先写主表,再写从表(从表的外键值必须在主表中存在);删除顺序相反,必须先删从表,再删主表(除非设置了 ON DELETE CASCADE)。
  • 外键的性能问题:高并发写入场景,外键会触发数据库的关联校验,增加数据库开销,可能导致死锁;互联网高并发场景,很多业务会放弃外键,在业务代码层实现数据一致性。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
MySQL约束
https://umami.eu.cc/posts/mysql-constraints/
作者
迷失的天际
发布于
2026-04-11
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
迷失的天际
趁现在,享受短暂的人生吧!
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
8
标签
37
总字数
76,162
运行时长
0 天
最后活动
0 天前

目录