MySQL约束那些事(超级详细,附带代码解析)

约束

1、约束概述

1.1 为什么需要约束

数据完整性是指数据的精确性和可靠性。它是防止数据库中存在不符合语义规定的数据和防止错误信息的输入输出造成无效操作或错误信息而提出的。

为了保证数据的完整性,SQL规范以约束的方式对表数据进行额外的条件限制。从以下四个方面考虑:

  • 实体完整性:例如,同一个表中,不能存在两条完全相同无法区分的记录
  • 域完整性:例如,年龄范围是0~120,性别范围是男/女
  • 引用完整性:例如:员工所在部门,在部门表中要能找到这个部门
  • 用户自定义完整性:例如:用户名唯一、密码不能为空等,本部门经理的工资不能高于本部门职工的平均工资的5倍

1.2 什么是约束

约束是表级的强制规定。对表中字段的限制。

1.3 约束的分类

角度1:约束的字段的个数

  • 单列约束
  • 多列约束

角度2:约束的作用范围

  • 列级约束:将此约束声明在对应的字段的后面
  • 表级约束:在表中所有字段都声明完,在所有字段的后面声明的约束

角度3:约束的作用(或功能)

  • not null(非空约束)
  • unique(唯一性约束)
  • primary key(主键约束)
  • foreign key(外键约束)
  • check(检查约束)
  • default (默认值约束)

1.4 如何添加/删除约束?

CREATE TABLE时添加约束

ALTER TABLE时增加约束、删除约束。

2、如何查看表中的约束

# 如何查看表中的约束
SELECT * FROM information_schema.`TABLE_CONSTRAINTS` WHERE table_name = '表名称';

2、非空约束

2.1 作用

限定某个字段/某列的值不允许为空

2.2 关键字

NOT NULL

2.3 特点

  • 默认,所有的类型的值都可以为NULL,包括INT,FLOAT等数据类型
  • 非空约束只能出现在表独享的列上,只能某个列单独限定非空,不能组合非空
  • 一个表可以有很多列都分别限定了非空
  • 空字符串 不等于NULL,0也不等于NULL

2.4 添加非空约束

(1)建表时:

CREATE TABLE 表名称(
	字段名 数据类型,
		字段名 数据类型 NOT NULL,
		字段名 数据类型 NOT NULL
);
举例:
CREATE TABLE test1(
	id INT NOT NULL,
	last_name VARCHAR(15) NOT NULL,
	email VARCHAR(25),
	salary DECIMAL(10,2)
);
DESC test1;

(2)在ALTER TABLE时添加约束


# 3.2在ALTER TABLE时添加约束
ALTER TABLE test1
MODIFY email VARCHAR(25) NOT NULL;

(3)在ALTER TABLE时删除约束

ALTER TABLE test1
MODIFY email VARCHAR(25) NULL;

3、唯一性约束

3.1 作用

用来限制某个字段/某列的值不能重复。

3.2 关键字

UNIQUE

3.3 特点

  • 同一个表中可以有多个唯一约束
  • 唯一约束可以是某一个列的值是唯一
  • 唯一性约束运行值为空
  • 在创建唯一的约束时,如果不给他唯一约束命名,就默认和列名相同
  • MySQL会给唯一约束的列上默认创建一个唯一索引。

3.4添加唯一约束

(1)建表时:在CREATE TABLE时添加约束

CREATE TABLE test2(
	id INT UNIQUE, # 列级约束
	last_name VARCHAR(15),
	email VARCHAR(25),
	salary DECIMAL(10,2),
	# 表级约束
	CONSTRAINT uk_test2_email UNIQUE(email)
);

在创建唯一约束的时候,如果不给唯一约束命名,就默认和列名相同。

可以向声明为unique的字段上添加NULL值,而且可以多次添加NULL值

(2)在ALTER TABLE时添加约束

# 字段列表中如果是一个字段,表示该列的值是唯一。如果是两个或更多个字段,那么复合唯一,即多个字段的组合是唯一的
# 方式1:
ALTER TABLE 表名称 ADD UNIQUE KEY(字段列表);
# 方式2:
ALTER TABLE 表名称 MODIFY 字段名 字段类型 UNIQUE;

(3)复合的唯一性约束

CREATE TABLE USER(
	id INT,
	`name` VARCHAR(15),
	`password` VARCHAR(25),
	#表级约束
	CONSTRAINT uk_user_name_pwd UNIQUE(`name`,`password`)
	
);
SELECT * FROM USER;
INSERT INTO USER VALUES(1,'TOM','ABC');
INSERT INTO USER VALUES(2,'Jerry','ABC');

(4) 删除唯一性约束

添加唯一性约束的列上也会自动创建唯一索引

删除唯一约束只能通过删除唯一索引的方式删除

删除时需要指定唯一索引名,唯一索引名就和唯一约束名一样

如果创建唯一约束是未指定名称,如果是单列,就默认和列名相同;如果是组合列,那么就默认和()中排第一位的列名相同

ALTER TABLE 表名 DROP INDEX 索引名;

4、PRIMARY KEY约束

4.1作用

用来唯一标识表中的一行记录

4.2 关键字

primary key

4.3 特点

  • 主键约束相当于唯一约束+ 非空约束的集合,主键约束列不允许重复,也不允许出现空值。
  • 一个表最多只能有一个主键约束,建立主键约束可以在列级别创建,也可以在表级别上创建。
  • 主键约束对应着表中的一列或者多列(复合主键)。
  • 如果是多列组合的符合主键约束,那么这些列都不允许为空值,并且组合的值不允许重复。
  • MySQL的主键名总是PRIMARY,就算自己命名了主键约束名也没用。
  • 当创建主键约束时,系统默认会在所在的列或列组合上建立对应的主键索引(能够根据主键查询的,就根据主键查询,效率更高)。如果删除主键约束了,主键约束对应的索引就自动删除了。
  • 需要注意的一点是,不要修改主键字段的值。因为主键是数据记录的唯一标识,如果修改了主键的值,就有可能会破坏数据的完整性。

4.4 添加主键约束

(1)建表时指定主键约束

CREATE TABLE 表名称(
	字段名称 数据类型 PRIMARY KEY, #列级模式
    字段名称 数据类型
);

 CREATE TABLE test3(
	id INT PRIMARY KEY,
	last_name VARCHAR(25),
	salary DECIMAL(10,2),
	email VARCHAR(25)
 );

(2)在ALTER TABLE时添加主键约束

ALTER TABLE test4 ADD PRIMARY KEY(id);

(3)删除主键约束

ALTER TABLE 表名称 DROP PRIMARY KEY;
# 说明:删除主键约束,不需要指定朱建明,因为一个表只有一个主键,删除主键约束后,非空还存在。

5、自增列:AUTO_INCREMENT

5.1作用

某个字段的自增

5.2 关键字

auto_increment

5.3 特点和要求

  1. 一个表最多只能有一个自增长列
  2. 当需要产生唯一标识符或顺序值时,可设置自增长
  3. 自增长列约束的列必须是键列(主键列,唯一键列)
  4. 自增约束的列的数据类型必须是整数类型
  5. 如果自增列指定了0和NULL,会在当前最大值的基础上自增,如果自增列手动指定了具体值,直接赋值为具体值。

5.4 如何指定自增约束

CREATE TABLE test7(
 id INT PRIMARY KEY AUTO_INCREMENT,
 last_name VARCHAR(15)
)

6、FOREIGN KEY约束

6.1 作用

限定某个表的某个字段的引用完整性

比如:员工表的员工所在部门的选择,必须在部门表能够找到对应的部分。、

6.2 关键字

foreign key

6.3 主表和从表/父表和子表

主表(父表):被引用的表,被参考的表

从表(子表):引用别人的表,参考别人的表

6.4 特点

(1)从表的外键列,必须引用/参考主表的键主键或唯一约束的列

为什么?因为被依赖/被参考的值必须是唯一的

(2)在创建外键约束时,如果不给外键约束命名。默认名不是列名,而是自动产生一个外键名,也可以指定外键约束名

(3)创建表时就指定外键约束的话,先创建主表,再创建从表

(4)删表时,先删从表,再删主表

(5)当主表的记录被从表参考时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据

(6)在“从表”中指定外键约束,并且一个表可以建立多个外键约束

(7)从表的外键列与主表被参考的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一样,创建子表时,就会出现错误。

(8)当创建外键约束时,系统默认会在所在的列上建立对应的普通索引,但是索引名不是列名,不是外键的约束名。(根据外键查询效率更高)

(9)删除外键约束后,必须手动删除对应的索引

添加外键约束

(1)建表时

# 7、foreign key(外键约束)
# 7.1 CREATE TABLE
# 主表和从表:父表和子表
# 先创建主表
CREATE TABLE dept1(
	dept_id INT,
	dept_name VARCHAR(15)
);
ALTER TABLE dept1 ADD PRIMARY KEY(dept_id);
# 再创建从表
CREATE TABLE emp1(
	emp_id INT PRIMARY KEY AUTO_INCREMENT,
	emp_name VARCHAR(15),
	departmenmt_id INT,
	# 表级约束
	CONSTRAINT fk_emp1_dept_id FOREIGN KEY(departmenmt_id) REFERENCES dept1(dept_id)
);


#演示外键的效果
INSERT INTO dept1 VALUES(10, 'IT');
INSERT INTO emp1 VALUES(10001,'TOM',10)

6.7 约束等级

  • Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录
  • Set null方式:在父表盘上update/delete记录时,将子表上匹配记录的列设为null,但是需要注意子表的外键列不能为not null
  • No action方式:如果子表有匹配的记录,则不允许对父表对应候选键进行update/delete操作
  • Restrict方式:同no action,都是立即检测外键约束
  • Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别

如果没有指定等级,就相当于Restrict方式

对于外键约束,最好是采用 ON UPDATE CASCADE ON DELETE RESTRICT的方式。

6.8 删除外键约束

1)第一步先查看约束名和删除外键约束
SELECT * FROM information_schema.`TABLE_CONSTRAINTS` WHERE table_name = '表名称';
ALTER TABLE 从表名 DROP FOREIGN KEY 外键约束名;
(2)第二步查看索引名和删除索引(注意,只能手动删除)
SHOW INDEX FROM 表名称; # 查看某个表的索引名
ALTER TABLE 从表名 DROP INDEX 索引名;

6.9 开发场景

问题1:如果两个表之间有关系(一对一、一对多),比如:员工表和部门,他们之间是否一定要建立外键约束?

不是的

问题2:建和不建外键约束有什么区别?

建外键约束,你的操作(创建表、删除表、增删改)会受到限制

不建外键约束,你的操作(创建表、删除表、增删改)会受到限制

外键与级联更适用于单机地并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度、

7、CHECK约束

7.1 作用

检查某个字段的值是否符合xx要求,一般是指值的范围

7.2 关键字

CHECK

7.3 说明:MySQL5.7不支持

但是MySQL8.0支持

# CHECK约束
CREATE TABLE test10(
	id INT,
	last_name VARCHAR(15),
	salary DECIMAL(10,2) CHECK(salary > 2000)
);
# 报错 :Check constraint 'test10_chk_1' is violated.
INSERT INTO test10(id,last_name, salary) VALUES(1,'Tom',250);
# 正确:
INSERT INTO test10(id,last_name, salary) VALUES(1,'Tom',2500);
SELECT * FROM test10;
  • 13
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

允谦呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值