MySQL 约束详解:保障数据完整性的六大机制
约束(Constraint)是 MySQL 中用于限制表中数据的规则,通过强制数据满足特定条件,确保数据库的完整性、一致性和准确性。MySQL 支持六大类约束,虽然部分约束在实现上有局限,但仍是设计可靠数据表的核心工具。
六大约束类型及作用
约束类型 |
作用描述 |
MySQL 支持情况 |
NOT NULL |
限制字段值不能为 NULL (必须填写)。 |
完全支持 |
DEFAULT |
为字段设置默认值,当插入数据时未指定该字段则使用默认值。 |
完全支持 |
PRIMARY KEY |
主键约束,唯一标识表中的每行记录,要求字段值唯一且非空。 |
完全支持(单字段或复合主键) |
UNIQUE |
唯一约束,保证字段值在表中唯一,但允许为 NULL(NULL 可重复)。 |
完全支持 |
CHECK |
检查约束,限制字段值必须满足指定条件(如 age > 0 )。 |
MySQL 8.0.16+ 支持,低版本仅语法兼容但不生效 |
FOREIGN KEY |
外键约束,限制两个表的关系,确保从表字段值必须来自主表的关联字段。 |
支持,但需存储引擎为 InnoDB(MyISAM 不支持) |
约束的使用方法
1. NOT NULL(非空约束)
确保字段必须有值,禁止插入 NULL
。
1 2 3 4 5 6 7 8
| CREATE TABLE student ( id INT, name VARCHAR(50) NOT NULL, age INT NOT NULL DEFAULT 0 );
INSERT INTO student (id) VALUES (1);
|
2. DEFAULT(默认约束)
为字段设置默认值,简化插入操作(未指定字段时自动填充)。
1 2 3 4 5 6 7 8 9 10
| CREATE TABLE employee ( id INT, name VARCHAR(50) NOT NULL, department VARCHAR(30) DEFAULT '未知部门', hire_date DATE DEFAULT CURRENT_DATE() );
INSERT INTO employee (id, name) VALUES (1, '张三');
|
3. PRIMARY KEY(主键约束)
主键是表的 “唯一标识符”,具有以下特性:
- 一个表只能有一个主键(可由多个字段组成复合主键)。
- 主键字段值必须唯一且非空。
- 主键会自动创建索引,提升查询效率。
示例 1:单字段主键
1 2 3 4
| CREATE TABLE user ( id INT PRIMARY KEY, username VARCHAR(50) NOT NULL );
|
示例 2:复合主键(多字段联合唯一)
1 2 3 4 5 6 7
| CREATE TABLE student_course ( student_id INT, course_id INT, score INT, PRIMARY KEY (student_id, course_id) );
|
4. UNIQUE(唯一约束)
确保字段值唯一,但允许 NULL
(多个 NULL
不冲突)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| CREATE TABLE teacher ( id INT PRIMARY KEY, email VARCHAR(100) UNIQUE, phone VARCHAR(20) UNIQUE );
INSERT INTO teacher (id, email) VALUES (1, 'a@school.com');
INSERT INTO teacher (id, email) VALUES (2, 'a@school.com');
INSERT INTO teacher (id, email, phone) VALUES (3, 'b@school.com', NULL); INSERT INTO teacher (id, email, phone) VALUES (4, 'c@school.com', NULL);
|
5. CHECK(检查约束)
限制字段值必须满足指定条件(如范围、格式等)。注意:MySQL 8.0.16 之前仅支持语法,不实际生效。
1 2 3 4 5 6 7 8 9
| CREATE TABLE product ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, price DECIMAL(10,2) CHECK (price > 0), stock INT CHECK (stock >= 0) );
INSERT INTO product (id, name, price) VALUES (1, '手机', -1000);
|
6. FOREIGN KEY(外键约束)
用于关联两个表(主表和从表),确保从表的字段值必须在主表的关联字段中存在,维护表间数据一致性。
示例:学生表(从表)关联班级表(主表)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| CREATE TABLE class ( class_id INT PRIMARY KEY, class_name VARCHAR(50) NOT NULL );
CREATE TABLE student ( student_id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, class_id INT, FOREIGN KEY (class_id) REFERENCES class(class_id) ON DELETE CASCADE ON UPDATE CASCADE );
|
外键约束的关联动作(可选):
ON DELETE CASCADE
:主表记录删除,从表关联记录自动删除。
ON DELETE SET NULL
:主表记录删除,从表关联字段设为 NULL
(需从表字段允许 NULL
)。
ON UPDATE CASCADE
:主表主键更新,从表关联字段自动更新。
约束的添加与删除
1. 新建表时添加约束
如上述示例,在 CREATE TABLE
语句中直接定义约束。
2. 已有表添加约束
1 2 3 4 5 6 7 8 9 10 11 12 13
| ALTER TABLE student MODIFY name VARCHAR(50) NOT NULL;
ALTER TABLE teacher ADD UNIQUE (email);
ALTER TABLE user ADD PRIMARY KEY (id);
ALTER TABLE student ADD FOREIGN KEY (class_id) REFERENCES class(class_id);
|
3. 删除约束
1 2 3 4 5 6 7 8 9 10 11
| ALTER TABLE student MODIFY name VARCHAR(50) NULL;
ALTER TABLE teacher DROP INDEX email;
ALTER TABLE user DROP PRIMARY KEY;
ALTER TABLE student DROP FOREIGN KEY student_ibfk_1;
|
约束的设计原则
- 最小必要原则:只添加必需的约束,避免过度约束导致插入 / 更新困难。
- 主键必设原则:几乎所有表都应设置主键(便于唯一标识记录和关联其他表)。
- 外键慎用原则:外键会降低写入性能,且可能导致表结构耦合。实际项目中,常通过业务逻辑维护表间关系,而非依赖外键约束。
- CHECK 替代方案:对于 MySQL 低版本,可用触发器(Trigger)或应用层验证替代
CHECK
约束。
v1.3.10