MySQL学习·第三站~
本文已收录至专栏:MySQL通关路
❤️每章节附章节思维导图,文末附全文思维导图,感谢各位点赞收藏支持~
约束是作用于表中字段上的规则,用于限制存储在表中的数据。 使用约束可以保证数据库中数据的正确、有效性以及完整性。我们可以在创建表或修改表的时候在表字段上添加约束。
约束分为如下几种:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的、可以为空 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束 | 插入数值时根据指定条件校验合法性(8.0.16版本之后开始) | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
我们先通过一个示例介绍前五个约束,最后再介绍外键约束~
在开发过程中,如果我们想要持久化存储数据就不可避免的需要建立相关表。而建表以后对于插入其中的数据,如果我们后台没有校验,数据库也没有约束的话将显得十分混乱,接下来我们通过指定约束来规范数据。
字段名 | 字段含义 | 字段类型 | 约束条件 | 约束关键字 |
---|---|---|---|---|
id | ID唯一标识 | int | 主键,并且自动增长 | PRIMARY KEY, AUTO_INCREMENT |
name | 姓名 | varchar(10) | 不为空,并且唯一 | NOT NULL , UNIQUE |
age | 年龄 | int | 大于0,并且小于等 于120 | CHECK |
status | 状态 | char(1) | 如果没有指定该值, 默认为1 | DEFAULT |
test | 测试 | int | 无约束对比测试字段 | 无 |
在创建表的时候为字段添加约束时,我们只需要在字段类型之后加上约束的关键字即可。例如:
CREATE TABLE user(
id int AUTO_INCREMENT PRIMARY KEY COMMENT 'ID唯一标识',
name varchar(10) NOT NULL UNIQUE COMMENT '姓名' ,
age int check (age > 0 && age <= 120) COMMENT '年龄' ,
status char(1) default '1' COMMENT '状态',
test int COMMENT '无约束对比测试字段'
);
特别说明:
check
约束时,约束条件必须写在()
中。default
约束指定默认值时,默认值必须符合字段数据类型。PRIMARY KEY
约束。我们重新创建一张没有约束的user表来演示~
primary key
)alter table 表名 add primary key(表字段名);
unique
)add table 表名 add unique(表字段名);
not null
)alter table 表名 modify 字段名 数据类型 not null
default
)alter table 表名 modify 字段名 数据类型 default 默认值;
check
)alter table 表名 add constraint 字段名 check(约束条件);
上述我们已经完成了约束的创建,接下来我们来测试一下约束是否生效~
外键约束通过作用于两张表之间,用于相互约束彼此的行为,从而保证数据的一致性和完整性。
例如下述,左侧的emp表是员工表,里面存储员工的基本信息,包含员工的ID、姓名、年龄、职位、薪资、入职日 期、上级主管ID、部门ID,在员工的信息中存储的是部门的ID dept_id,而这个部门的ID是关联的 部门表dept的主键id,emp表的dept_id就是外键,关联的是另一张dept表的主键。
我们可以看出这两张表之间存在着一种关联关系,但它们只是在逻辑上存在这样一层关系;在数据库层面,并未建立外键关联。也就说emp表中的dept_id值可以为任意数值,即是dept表中不存在。而dept表中字段被emp使用了也可以随意删除。 因此无法保证数据的一致性和完整性的。这时候就需要我们严格的进行手动维护或者使用外键约束。
特别说明:
CREATE TABLE 表名(
字段名 数据类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY (子表字段名) REFERENCES 父表 (父表字段名)
);
# 必须先创建需要关联的父表 (dept)
create table emp(
id int auto_increment comment 'ID' primary key,
name varchar(50) not null comment '姓名',
age int comment '年龄',
job varchar(20) comment '职位',
salary int comment '薪资',
entrydate date comment '入职时间',
managerid int comment '直属领导ID',
dept_id int comment '部门ID',
CONSTRAINT fk_dept_id foreign key (dept_id) references dept(id)
)comment '员工表';
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (子表字段名) REFERENCES 父表 (父表字段名);
添加外键约束后我们无法随意删除父表中的数据,必须先删除所有子表中关联到改记录的数据才能删除父表中数据。
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
在添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
行为 | 说明 |
---|---|
NO ACTION |
当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不 允许删除/更新。 (与 RESTRICT 一致) 默认行为 |
RESTRICT |
当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不 允许删除/更新。 (与 NO ACTION 一致) 默认行为 |
CASCADE |
当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则 也删除/更新外键在子表中的记录。 |
SET NULL |
当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表 中该外键值为null(这就要求该外键允许取null)。 |
SET DEFAULT |
父表有变更时,子表将外键列设置成一个默认的值 (Innodb存储引擎不支持) |
注意事项:NO ACTION
与RESTRICT
为外键约束的默认行为,也就是在一些情况下阻止我们删除/更新数据,添加外键时默认生效。如果需要修改为其他几种行为则需要我们在添加外键时手动设置。
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES
父表名 (父表字段名) ON UPDATE [更新行为] ON DELETE [删除行为]