1、什么是约束
约束是表级
的强制规定
2、为什么使用约束
是为了保证表中数据的完整性,完整性又可以拆分为精确性和可靠性
3、怎么去保证数据完整性呢,从以下四个角度进行考虑
4、约束的分类
5、如何添加约束
6、如何查看约束
需要到information_schema``这个库下,查询TABLE_CONSTRAINTS
这个表
例如我需要查询t_decade_test
表中存在哪些约束,就可以使用
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = 't_decade_test';
1)如何在建表时创建非空约束
CREATE TABLE t_decade_test_not_null(
id INT NOT NULL,
last_name VARVHAR(20) NOT NULL,
email VARCHAR(25),
salary DECIMAL(10,2)
);
2)创建完这个表后,如下几种情况会报错
3)如何使用ALTER TABLE添加约束,我们还是以之前的t_decade_test_not_null为例
对email字段添加一个非空约束,但是如果email字段已经存在null值,那么下方的语句是无法执行的
ALTER TABLE t_decade_test_not_null
MODIFY email VARCHAR(25) NOT NULL;
4)如何使用ALTER TABLE删除约束呢?其实只要把NOT NULL改成NULL即可
ALTER TABLE t_decade_test_not_null
MODIFY email VARCHAR(25) NULL;
1)如何在建表时,给字段添加唯一性约束
CREATE TABLE t_decade_test_unique(
id INT UNIQUE #这就是列级约束,
last_name VARVHAR(20),
email VARCHAR(25),
salary DECIMAL(10,2),
# 添加表级约束,一般约束的命名格式为:作用_表名_字段
CONSTRAINT uk_t_decade_test_unique_email UNIQUE(email)
);
2)如何使用ALTER TABLE
来添加约束
方式一:alter table 表名 add UNIQUE(字段名称)
alter table t_decade_test_unique add UNIQUE(lastname);
# 如果要给约束取名,还是使用constraint
alter table t_decade_test_unique add constraint uk_t_decade_test_unique_lastname UNIQUE(lastname,email);
方式二:alter table 表名 modify 字段名 字段类型 UNIQUE
alter table t_decade_test_unique MODIFY last_name VARVHAR(20) UNIQUE;
3)什么是复合的唯一性约束
可以理解为,我们对多个字段进行组合
要求两条数据中,这几个字段的值不能完全相同,必须有一个或者几个字段的值不一样
CREATE TABLE t_unique_user(
id INT,
user_name VARCHAR(20),
user_pwd VARCHAR(15),
constraint uk_t_unique_user_nameAndPwd UNIQUE(user_name,user_pwd);
);
这样一来,这个表中的任意两条数据,name和pwd字段就不能完全相同
4)删除唯一性约束
删除唯一索引
的方式来删除该约束唯一索引的名和唯一性约束的名称是一样的
()
中排在第一位的字段名相同。当然我们也可以使用constraint
来自定义约束名alter table t_unique_user
DROP index 索引名;
我们也可以通过show index from 表名;
查看表的索引
唯一性约束+非空约束
一个表中只能有一个主键约束
,它可以在列级别创建,也可以在表级别创建PRIMARY
,它不能像前面的唯一性约束一样自定义名称1)创建表时,如何添加主键约束
列级约束
CREATE TABLE t_test_primary_key(
id INT PRIMARY KEY,
last_name VARCHAR(20),
salary DECIMAL(10,2),
email VARCHAR(15)
);
或者表级约束
CREATE TABLE t_test_primary_key(
id INT,
last_name VARCHAR(20),
salary DECIMAL(10,2),
email VARCHAR(15),
constraint prk_t_test_primary_key_id PRIMARY KEY(id) #这里的名称是无效的
);
或者复合主键
CREATE TABLE t_test_table(
id INT,
user_name VARCHAR(20),
user_pwd VARCHAR(15),
PRIMARY KEY(user_name,user_pwd)
);
2)使用ALTER TABLE创建主键约束
ALTER TABLE table_name
ADD PRIMARY KEY (column_name);
3)删除主键约束
ALTER TABLE table_name
DROP PRIMARY KEY;
整数类型
,在没有给第一条数据的该字段显式赋值情况下,默认从1开始1)在建表时声明自增列
CREATE TABLE t_auto_increment(
id INT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20)
);
2)使用alter table声明自增列
ALTER TABLE t_auto_increment
MODIFY id INT AUTO_INCREMENT;
3)删除自增
ALTER TABLE t_auto_increment
MODIFY id INT;
4)MySQL5.7与MySQL8.0中计数器的差别
假设现在有一个场景,我们连续执行三次insert语句,id字段value都是0
使用select语句后,我们可以发现三条数据的id依次为1,2,3
现在我们同时在两个版本的MySQL中删除id为3的数据
然后重复执行insert id为0这个操作
然后可以发现,两个版本的MySQL中,该表中的第三条数据并不是从3开始了,而是从4开始
然后,我们删除id为4的这条数据,再对两个版本的MySQL服务都进行重启操作,继续重新insert id=0这个操作,我们可以发现
MySQL5.7中,自增主键的计数器是在内存中
维护的,数据库重启后,计数器会被初始化
MySQL8.0中,自增主键的计数器会被持久化到重做日志
中,每次计数器发生改变都会记录到该日志中,当数据库重启,InnoDB会根据重做日志来初始化计数器的内存值
1)在create table时指定外键约束
CREATE TABLE t_dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
department_id INT,
# 使用表级约束的方式指定外键约束
constraint fk_emp_department_id FOREIGN KEY (department_id) REFERENCES t_dept (dept_id)
);
2)演示外键效果
在创建了t_dept和t_emp表之后
如果两张表都是空表,当我们直接执行insert into t_emp values(1,"decade",10);
SQL执行会报错,因为我们从表t_emp依赖的主表t_dept中并没有id为10的记录
所以我们要先执行
insert into t_dept values(10,"技术部");
再执行insert into t_emp values(1,"decade",10);
执行上述插入语句之后
假设我们执行delete from t_dept where id = 10;
,语句还是会报错,因为这条数据被从表依赖
同样的,当我们执行update t_dept set id = 20 where dept_name = '技术部';
时,语句也会报错
3)建表后如何使用alter table添加外键约束
CREATE TABLE t_dept2(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp2(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
department_id INT
);
ALTER TABLE t_emp2
ADD CONSTRAINT fk_emp2_department_id FOREIGN KEY (department_id) REFERENCES t_dept2 (dept_id);
4)外键约束的约束等级
Cascade方式
:当父表的数据发生update/delete时,同步update/delete子表中引用此记录的数据Set null方式
:当父表的数据发生update/delete时,将子表中引用此记录的外键列设置为null,注意,子表的外键列不允许有非空约束No action方式
:如果子表中有引用父表记录的数据,那么不允许对父表对应候选键进行update/delete操作Restrict方式
:同No action
方式Set default方式
:父表有变更时,将子表的外键列设置成一个默认值,但InnoDB不能识别对于外键约束,最好使用ON UPDATE CASCADE ON DELETE RESTRICT
的方式
即更新会同步,但是不允许删除,使用方式如下
CREATE TABLE t_dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
department_id INT,
# 使用表级约束的方式指定外键约束
constraint fk_emp_department_id FOREIGN KEY (department_id) REFERENCES t_dept (dept_id) ON UPDATE CASCADE ON DELETE RESTRICT
);
5)删除外键约束
# 第一步:先查看表中的约束名,删除约束
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE table_name = '表名称';
ALTER TABLE 从表名
DROP FOREIGN KEY 外键约束名称;
# 第二步:查看索引名和删除索引
SHOW INDEX FROM 表名称;
ALTER TABLE 从表名 DROP INDEX 索引名;
6)开发场景
阿里开发规范要求,不得使用外键与级联(可以理解为主表数据更新触发从表相应记录更新),外键与级联适合单机低并发场景,不适合分布式、高并发场景,级联可能导致数据库更新风暴,外键影响数据库插入速度,所以一切外键概念都应该在应用层,即Java代码层面进行解决(经典白学~)
1)建表时添加
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2) CHECK(salary>5000)
);
如果你执行insert into t_emp values(1, "彭于晏", 1500);
,语句就会报错
1)在创建表时添加约束
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2) DEFAULT 3000
);
如果你执行insert into t_emp values(1, "彭于晏");
,那么此条数据对应salary那一列的值就是3000
2)使用ALTER TABLE添加约束
CREATE TABLE t_emp(
id iNT PRIMARY KEY AUTO_INCREMENT
last_name VARCHAR(20),
salary DECIMAL(10,2)
);
ALTER TABLE t_emp
MODIFY salary DECIMAL(10,2) DEFAULT 3000;
3)删除约束
ALTER TABLE t_emp
MODIFY salary DECIMAL(10,2);
很长时间没有更新博客了,最近也不知道在瞎忙什么,后面会慢慢恢复之前的学习状态,人还是要不断学习,才不会被时代抛弃,希望自己这次坚持的久一点,hh~
如有错误,欢迎指正!!!