【MySQL】约束(三)

MySQL学习·第三站~
本文已收录至专栏:MySQL通关路
❤️每章节附章节思维导图,文末附全文思维导图,感谢各位点赞收藏支持~

一.引入

约束作用于表中字段上规则,用于限制存储在表中的数据。 使用约束可以保证数据库中数据的正确、有效性以及完整性。我们可以在创建表或修改表的时候在表字段上添加约束。

约束分为如下几种:

约束 描述 关键字
非空约束 限制该字段的数据不能为null NOT NULL
唯一约束 保证该字段的所有数据都是唯一、不重复的、可以为空 UNIQUE
主键约束 主键是一行数据的唯一标识,要求非空且唯一 PRIMARY KEY
默认约束 保存数据时,如果未指定该字段的值,则采用默认值 DEFAULT
检查约束 插入数值时根据指定条件校验合法性(8.0.16版本之后开始) CHECK
外键约束 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 FOREIGN KEY

我们先通过一个示例介绍前五个约束,最后再介绍外键约束~

二.普通约束

【MySQL】约束(三)_第1张图片

(1) 示例说明

在开发过程中,如果我们想要持久化存储数据就不可避免的需要建立相关表。而建表以后对于插入其中的数据,如果我们后台没有校验,数据库也没有约束的话将显得十分混乱,接下来我们通过指定约束来规范数据。

字段名 字段含义 字段类型 约束条件 约束关键字
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 无约束对比测试字段

(2) 建表时指定约束

在创建表的时候为字段添加约束时,我们只需要在字段类型之后加上约束的关键字即可。例如:

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约束。
  • 在一些正常情况下,可以在一个字段上使用多个约束条件
    【MySQL】约束(三)_第2张图片

(3) 建表后指定约束

我们重新创建一张没有约束的user表来演示~

  • 添加主键约束primary key
alter table 表名 add primary key(表字段名);

【MySQL】约束(三)_第3张图片

  • 添加唯一约束unique
add table 表名 add unique(表字段名);

【MySQL】约束(三)_第4张图片

  • 添加非空约束(not null)
alter table 表名 modify 字段名 数据类型 not null

【MySQL】约束(三)_第5张图片

  • 添加默认约束default
alter table 表名 modify 字段名 数据类型 default 默认值;

【MySQL】约束(三)_第6张图片

  • 添加检查约束(check)
alter table 表名 add constraint 字段名 check(约束条件);

在这里插入图片描述

(4) 插入测试

上述我们已经完成了约束的创建,接下来我们来测试一下约束是否生效~

  • 主键 + 自增
    【MySQL】约束(三)_第7张图片

  • 唯一 + 非空
    【MySQL】约束(三)_第8张图片

  • 默认约束
    【MySQL】约束(三)_第9张图片

  • 检查约束
    【MySQL】约束(三)_第10张图片

三.外键约束

【MySQL】约束(三)_第11张图片

外键约束通过作用于两张表之间,用于相互约束彼此的行为,从而保证数据的一致性和完整性。

(1) 引入

例如下述,左侧的emp表是员工表,里面存储员工的基本信息,包含员工的ID、姓名、年龄、职位、薪资、入职日 期、上级主管ID、部门ID,在员工的信息中存储的是部门的ID dept_id,而这个部门的ID是关联的 部门表dept的主键id,emp表的dept_id就是外键,关联的是另一张dept表的主键。
【MySQL】约束(三)_第12张图片

我们可以看出这两张表之间存在着一种关联关系,但它们只是在逻辑上存在这样一层关系;在数据库层面,并未建立外键关联。也就说emp表中的dept_id值可以为任意数值,即是dept表中不存在。而dept表中字段被emp使用了也可以随意删除。 因此无法保证数据的一致性和完整性的。这时候就需要我们严格的进行手动维护或者使用外键约束

(2) 添加外键

特别说明:

  • 添加外键时必须得确保需要关联的父表已经创建
  • 一个表可存在多个外键,且可以关联多个表

(2.1) 建表时添加

  • 语法说明
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 '员工表';

【MySQL】约束(三)_第13张图片

(2.2) 建表后添加

  • 语法说明
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (子表字段名) REFERENCES 父表 (父表字段名);
  • 示例演示
    在这里插入图片描述
    【MySQL】约束(三)_第14张图片

(2.3) 外键测试

添加外键约束后我们无法随意删除父表中的数据,必须先删除所有子表中关联到改记录的数据才能删除父表中数据。
【MySQL】约束(三)_第15张图片

(3) 删除外键

  • 语法
ALTER TABLE  表名   DROP  FOREIGN  KEY  外键名称;
  • 示例演示
    在这里插入图片描述

【MySQL】约束(三)_第16张图片

(4) 删除/更新行为

在添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:

行为 说明
NO ACTION 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不 允许删除/更新。 (与 RESTRICT 一致) 默认行为
RESTRICT 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不 允许删除/更新。 (与 NO ACTION 一致) 默认行为
CASCADE 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则 也删除/更新外键在子表中的记录。
SET NULL 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表 中该外键值为null(这就要求该外键允许取null)。
SET DEFAULT 父表有变更时,子表将外键列设置成一个默认的值 (Innodb存储引擎不支持)

注意事项:NO ACTIONRESTRICT为外键约束的默认行为,也就是在一些情况下阻止我们删除/更新数据,添加外键时默认生效。如果需要修改为其他几种行为则需要我们在添加外键时手动设置。

  • 修改删除/更新语法:
ALTER TABLE  表名  ADD CONSTRAINT  外键名称  FOREIGN KEY  (外键字段)   REFERENCES   
父表名 (父表字段名)  ON UPDATE [更新行为] ON DELETE [删除行为]
  • CASCADE行为演示
    【MySQL】约束(三)_第17张图片
    【MySQL】约束(三)_第18张图片

  • SET NULL行为演示
    【MySQL】约束(三)_第19张图片

【MySQL】约束(三)_第20张图片

四.全文概览

【MySQL】约束(三)_第21张图片

你可能感兴趣的:(MySQL通关路,mysql,数据库)