一、约束的基本概念
1. 什么是约束
约束是数据库为了保证数据的完整性、准确性、有效性,对表数据添加的强制性规则。
- 作用:减少数据冗余、避免无效数据、维护数据一致性
- 分类:主键约束、唯一约束、非空约束、默认约束、外键约束
二、五类约束详解(附 SQL 示例)
(一)主键约束(PRIMARY KEY)
核心作用
- 唯一标识表中的每一行数据,不允许重复、不允许为空
- 一张表只能有一个主键 ,通常用
id字段作为主键
-
基础使用示例
-- 创建表时指定主键
CREATE TABLE student (
id INT PRIMARY KEY,
name VARCHAR(255),
age INT,
email VARCHAR(255)
);-- 错误示例:插入重复主键(会报错)
INSERT INTO student(id, name, age, email)
VALUES (1, '张三', 18, '1443005893@qq.com');
INSERT INTO student(id, name, age, email)
VALUES (1, '李四', 20, '1443005893@qq.com');
-- 报错:Duplicate entry '1' for key 'PRIMARY' -
自增主键(AUTO_INCREMENT)
为了避免手动维护主键重复,MySQL 提供了自增特性,让数据库自动维护主键值:
-- 创建自增主键表
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
age INT,
email VARCHAR(255)
);
-- 插入数据时无需指定 id,数据库自动生成
INSERT INTO student(name, age, email)
VALUES ('张三', 18, '1443005893@qq.com');
INSERT INTO student(name, age, email)
VALUES ('李四', 20, '1443005893@qq.com');
-
AUTO_INCREMENT 特点
-
仅整数类型字段可设置自增
-
仅主键字段可设置自增
-
自增字段插入数据时可不赋值
-
初始值默认从 1 开始,步长为 1
-
自增字段一旦被使用过,后续不会再出现(即使数据被删除)
(二)唯一约束(UNIQUE)
核心作用
- 保证列中数据不允许重复 ,但允许为空
- 一张表中可以创建多个唯一约束(与主键的核心区别)
- 注意:
VARCHAR(255)长度的字段,MySQL 无法设置唯一约束(索引长度限制)
使用示例
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
age INT,
email VARCHAR(255) UNIQUE -- 邮箱不允许重复
);
-- 第一次插入正常
INSERT INTO student(name, age, email)
VALUES ('张三', 18, '1443005893@qq.com');
-- 第二次插入重复邮箱,报错
INSERT INTO student(name, age, email)
VALUES ('lisi', 20, '1443005893@qq.com');
-- 报错:Duplicate entry '1443005893@qq.com' for key 'email'
(三)非空约束(NOT NULL)
核心作用
- 强制列中数据不允许为空,必须填写有效数据
- 常用于必填字段,如用户名、手机号、密码等
使用示例
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL, -- 姓名不允许为空
age INT,
email VARCHAR(255)
);
-- 错误示例:插入空姓名(会报错)
INSERT INTO student(name, age, email)
VALUES (NULL, 18, '1443005893@qq.com');
-- 报错:Column 'name' cannot be null
(四)默认约束(DEFAULT)
核心作用
- 为列设置默认值,当插入数据时不指定该列的值,会自动填充默认值
- 常用于性别、状态、创建时间等字段
使用示例
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
age INT DEFAULT 18, -- 年龄默认 18
gender CHAR(1) DEFAULT '男' -- 性别默认男
);
-- 插入数据时不指定 age 和 gender,自动使用默认值
INSERT INTO student(name) VALUES ('张三');
-- 查询结果:age=18, gender='男'
(五)外键约束(FOREIGN KEY)
核心作用
- 建立两张表之间的关联关系,保证数据的一致性、完整性
- 用于一对多、多对多关系中,实现表间联动
-
基础使用示例
-- 主表:部门表(父表)
CREATE TABLE dept (
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(50)
);-- 从表:员工表(子表),通过外键关联部门表
CREATE TABLE emp (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(50),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES dept(dept_id)
); -
外键字段配置项
| 配置项 | 说明 |
|---|---|
| 外键名(name) | 可省略,系统自动生成 |
| 字段(field) | 子表中用于关联的字段 |
| 参考数据库 | 外键关联的数据库 |
| 引用表(reference table) | 关联的主表 |
| 外栏位名(outside field) | 主表中被关联的字段 |
- 删除 / 更新时的联动规则
| 规则 | 作用 |
|---|---|
| CASCADE | 父表更新 / 删除记录时,子表对应记录同步更新 / 删除 |
| SET NULL | 父表更新 / 删除记录时,子表对应字段设为 NULL(子表字段需允许为空) |
| NO ACTION / RESTRICT | 子表有匹配记录时,禁止父表更新 / 删除操作 |
-
注意事项
-
添加外键时,引擎必须为
InnoDB -
外键字段必须与主表字段数据类型一致
-
主表字段必须是主键或唯一约束字段
-
外键会影响插入、更新、删除性能,数据仓库场景通常不建议使用
三、约束的综合应用示例(学生表完整设计)
CREATE TABLE student (
-- 主键约束 + 自增
id INT PRIMARY KEY AUTO_INCREMENT,
-- 非空约束
name VARCHAR(255) NOT NULL,
-- 默认约束
age INT DEFAULT 18,
-- 唯一约束
email VARCHAR(255) UNIQUE,
-- 外键约束(关联班级表)
class_id INT,
FOREIGN KEY (class_id) REFERENCES class(class_id)
);
四、约束设计最佳实践
- 主键设计 :优先使用自增
INT类型,避免使用业务字段作为主键(如学号、手机号) - 唯一约束:手机号、邮箱等字段建议添加唯一约束,避免重复数据
- 非空约束 :必填字段必须设置
NOT NULL,避免逻辑错误 - 外键使用:业务系统中可使用外键保证一致性;数据仓库、大数据场景建议通过应用层控制数据一致性,避免性能损耗
- 默认值设计:合理使用默认值,减少插入语句的冗余字段
五、约束常见报错与解决
| 报错场景 | 错误原因 | 解决方法 |
|---|---|---|
| Duplicate entry | 主键 / 唯一约束重复 | 检查插入数据是否重复,或使用自增主键 |
| Column cannot be null | 非空约束字段插入空值 | 为非空字段提供有效数据 |
| Foreign key constraint fails | 外键关联数据不存在 | 先插入主表数据,再插入子表 |