前言
在之前我整理了一篇关于数据库在对表的一些常用操作:增删改查,大家有兴趣可以去看看,这篇文章来梳理一下SQL约束,这是数据库表设计的根基
一、什么是约束?为什么要用?
约束=给数据表加的"规则"
为了确保表中的数据的完整性(准确性、正确性),为表添加一些限制。是数据库中表设计的一个最基本规则。使用约束可以使数据更加准确,从而减少冗余数据(脏数据)
主要分为五大类:

二、主键约束 PRIMARY KEY
1.定义
每一个数据表都必须有一个唯一主键作为数据的唯一标识,设置主键的列不允许为空,主键习惯 id 表示,可以在创建数据时直接指定,也可以通过修改表结构直接添加,设置为主键的列在添加数据时不能重复,即唯一性。
2.示例
当插入两条相同id的数据时,会报错:
sql
INSERT INTO student(id,name,age,email)
VALUES (1,'张三',18,'11111111@qq.com');
INSERT INTO student(id,name,age,email)
VALUES (1,'李四',20,'12222222@qq.com');

3.主键自增
手动维护主键太麻烦了,使用MySQL时,可以使用提供的自增功能,该功能时每次找到数据表中最大的ID值+1
(1)特点
- 只有整型数据列可以设置为自增
- 必须是主键
- 插入时不用给值
- 默认从 1 开始,每次 +1
- 用过的数字不会复用(删了也不回退)
(2)示例

三、唯一约束 UNIQUE
1.定义
唯一约束(可以为空+可以多个)用来保护表中某列数据不允许重复,与主键约束(非空+唯一)类似,但级别没有主键高。一份表中唯一约束可以创建多个,并且唯一约束的列允许为空。
注意varchar长度为255时,无法设置唯一约束。
唯一约束一般用于约束手机号、账户、邮箱等信息。

(2)示例
给email加上UNIQUE后,运行会报错
sql
INSERT INTO student(name,age,email)
VALUES ('张三',18,'111111@qq.com');
INSERT INTO student(name,age,email)
VALUES ('李四',20,'111111@qq.com');
四、非空约束 NOT NULL
1.作用
强制这一列必须填值,不可为NULL,但是可以为空字符串'',一张表可以有多个非空字段
比如:id、姓名、手机号、用户名,都必须加 NOT NULL。

2.示例
在建表的时候可以添加非空约束:
sql
-- 创建学生表,给姓名、手机号加非空约束
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL, -- 姓名:非空
phone VARCHAR(11) NOT NULL, -- 手机号:非空
age INT -- 年龄:允许为空
);
正确插入数据:
sql
-- 给所有非空字段正常赋值,执行成功
INSERT INTO student(name, phone, age)
VALUES ('张三','13800138000',18);
修改表,给指定字段添加/删除非空约束:
sql
-- 给已有字段添加非空约束
ALTER TABLE student MODIFY COLUMN age INT NOT NULL;
-- 移除非空约束(变回允许为空)
ALTER TABLE student MODIFY COLUMN age INT;
五、默认约束 DEFAULT
1.定义
给字段设置默认值 ,插入数据时不主动给该字段赋值,自动使用预设的默认值。
2.适用场景
- 用户状态默认:正常 (1)
- 逻辑删除默认:未删除 (0)
- 创建时间默认:当前时间
3.示例
建表语句:
sql
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
gender VARCHAR(10) DEFAULT '女', -- 性别默认女
status TINYINT DEFAULT 1, -- 状态1:正常
is_delete TINYINT DEFAULT 0 -- 逻辑删除0:未删除
);
不指定默认字段,自动填充默认值:
sql
-- 只插用户名,gender、status、is_delete 都不赋值
INSERT INTO user(username) VALUES ('李四');
主动赋值,覆盖默认值:
sql
-- 主动指定性别为男,会覆盖默认值
INSERT INTO user(username,gender) VALUES ('王五','男');
修改表,添加/删除默认约束:
sql
-- 给已有字段设置默认值
ALTER TABLE user MODIFY COLUMN status TINYINT DEFAULT 1;
-- 删除默认约束
ALTER TABLE user ALTER COLUMN status DROP DEFAULT;
六、外键约束 FOREIGN KEY
1.定义
外键约束:让子表字段关联主表主键 ,强制保证参照完整性。
- 主表(父表):被引用的表,如班级表 class
- 子表(从表):引用别人的表,如学生表 student
- 外键字段:子表中关联主表主键的字段,如 student.cid 关联 class.id
规则:子表外键的值,必须在主表主键中存在,不能随便写不存在的数据。
2.适用场景
- 学生归属班级:学生表关联班级表
- 订单关联用户:订单表关联用户表
- 商品关联分类:商品表关联分类表
3.示例
先建立主表:班级表
sql
-- 主表:班级表
CREATE TABLE class (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(20) NOT NULL COMMENT '班级名称'
);
再建子表:学生表,并添加外键
sql
-- 子表:学生表,cid 关联 class 表的 cid
CREATE TABLE student (
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL,
age INT,
cid INT COMMENT '所属班级id',
-- 定义外键
FOREIGN KEY (cid) REFERENCES class(cid)
);
测试:
sql
-- 先插入班级数据
INSERT INTO class(cname) VALUES ('一班'),('二班');
--正常插入:cid存在的例子
INSERT INTO student(sname,age,cid) VALUES ('张三',18,1);
--违规插入:cid不存在的例子,会报错
INSERT INTO student(sname,age,cid) VALUES ('李四',19,99);
4.外键规则(重点)
当主表删除/修改主键时,子表怎么处理,有四种规则:
(1)RESTRICT / NO ACTION(默认)
子表有关联数据,主表禁止删除 / 修改,保护数据安全。
(2) CASCADE 级联操作
主表改 id,子表自动跟着改;主表删记录,子表自动删关联记录。
sql
FOREIGN KEY (cid) REFERENCES class(cid) ON DELETE CASCADE ON UPDATE CASCADE
(3)SET NULL 置空
主表删除 / 修改后,子表外键字段自动设为 NULL。
要求:外键字段不能加 NOT NULL。
(4)SET DEFAULT
设置为默认值,InnoDB 引擎基本不支持,工作中不用记。
5.建议
在实际开发应用中,不会设置外键,因为设置外键会对性能有较大的影响