Pixiv - KiraraShss
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 KEY | UNIQUE |
|---|---|---|
| 非空限制 | 强制非空,不允许 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)。
- 外键的性能问题:高并发写入场景,外键会触发数据库的关联校验,增加数据库开销,可能导致死锁;
互联网高并发场景,很多业务会放弃外键,在业务代码层实现数据一致性。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
相关文章 智能推荐
1
多表查询
MySQL数据库 关于MySQL多表查询的相关语句
2
数据库的增删改查
MySQL数据库 关于MySQL数据库的增删改查语句
3
数据库表操作
MySQL数据库 针对数据库与表的操作,即数据定义语言
4
数据库的安装和配置
MySQL数据库 主要介绍数据库的作用以及MySQL的选择安装和配置
5
接口和接口测试的概念
接口测试 接口与接口测试一些理论知识
随机文章 随机推荐