④外键约束 foreign key
相关术语:外键约束:一种约束
外键字段:被添加了外键约束的字段
外键值:外键字段中的每一个值
当班级编号没有任何约束的时候,可能会导致数据无效。可能出现一个102,但是102班级不存在。所以,为了保证班级编号中的值都是100和101,需要添加外键约束。
使用外键后两表之间存在父子级关系,班级表因为被学生表引用,所以是父级表
删除表的顺序——先删子,再删父
创建表的顺序——先创父,再创子
删除数据的顺序——先删子,再删父
插入数据的顺序——先插父,再插子
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
classno int primary key,
classname varchar(255) not null
);
create table t_student(
no int primary key auto_increment,
name varchar(10) not null,
cno int,
foreign key(cno) references t_class(classno)
);
insert into t_class(classno,classname) values(
100,'高一1'),
(101,'高一2');
insert into t_student(name,cno) values('zhang san',100);
insert into t_student(name,cno) values('lisi',100);
insert into t_student(name,cno) values('wangwu',100);
insert into t_student(name,cno) values('zhaoliu',101);
insert into t_student(name,cno) values('wangqi',101);
insert into t_student(name,cno) values('wuba',101);
--?子表中的外键引用的父表中的某个字段,被引用的这个字段必须是主键吗?
不一定是主键,但至少有unique约束
--?外键值可以为null吗
可以
十二、存储引擎
1、存储引擎是mysql中特有的一个术语
实际上存储引擎是一个表存储/组织数据的方式
不同的存储引擎,表存储数据的方式不同
2、怎么给表添加/指定存储引擎
可以在建表的时候给表指定存储引擎
在建表时最后的右括号后面用engine指定存储引擎,用charset指定字符编码方式
mysql默认的存储引擎是 InnoDB
mysql默认的字符编码方式是:utf8
create table t_product(id int,name varchar(10),primary key(id))engine=innodb charset=utf8;
3、查看mysql支持的存储引擎
show engines \G
4、常用存储引擎
①MyISAM存储引擎
它管理的表具有以下特征:
使用三个文件表示每个表
格式文件-存储表结构的定义(mytable.frm)
数据文件-存储表行的内容(mytable.MYD)
索引文件-存储表上索引(mytable.MYI)
⚠对于一张表来说,只要是主键,或者加有unique约束的字段上会自动创建索引
②InnoDB存储引擎
支持事务,支持数据库崩溃后自动恢复机制
最主要的特点:非常安全
③MEMORY存储引擎
表数据及索引被存储在内存中 目的就是快,查询快
不能包含blob或text字段
缺点:不安全,关机之后数据消失
十三、事务
1、一个事务就是一个完整的业务逻辑
完整的业务逻辑——假设转账,1000块从A转到B,A减少1000,B增加1000,是一个完整的业务逻辑。
要么同时成功,要么同时失败。
⚠只有DML语句才有事务一说,其他语句与事物无关
insert delete update 和事务有关
一个事务其实就是多条DML语句同时成功或者同时失败
2、在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中
在事务的执行过程中,我们可以提交事务,也可以回滚事务。
>>>提交事务
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中
提交事务标志着,事务的结束。并且是一种全部成功的结束
>>>回滚事务
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
回滚事务标志着,事务的结束。并且是一种全部失败的结束
3、如何提交和回滚事务
提交事务:commit
回滚事务:rollback
mysql默认情况下是支持自动提交事务的
--?如何关闭mysql的自动提交机制
先执行:start transaction
再输入语句
commit之后就没法rollback回去了
只能回滚到上一次的提交点上
4、事务包括四个特性
A:原子性:事务是最小的工作单元,不可再分
C:一致性:所有事务要求,在同一个事务当中,所以操作必须同时成功,或者同时失败,以保证数据的一致性
I:隔离性:A事务和B事务之间具有一定的隔离
D:持久性:事务最终结束的一个保障
5、事务的隔离级别
①读未提交 read uncommitted(级别最低)
事务A可以读取到事务B未提交的数据
这种隔离级别存在的问题是脏读现象
②读已提交 read committed
事务A只能读取到事务B提交之后的数据
这种隔离级别解决了脏读的现象
不可重复读取数据,每一次读到的数据可能有变化,且绝对的真实
③可重复读 repeatable read
事务A开启之后,不管多久,每一次在事务A中读取到的数据都是一致的,即使事务B的数据已经修改并提交,事务A读取到的数据还是不会发生变化。
级别更高,解决了不可重复读取数据,等于说对数据的读取有约束,所以读取到的数据都是幻象,不够真实
mysql中默认的事务隔离级别是可重复读
等于说在事务开启时暂时存档
举例:银行从1点开始到3点算总账,这个时间区间有客户存款和取款,此时为了不影响总账的数据,需要用到可重复读级别
④序列化/串行化 serializable
效率最低,表示事务排队不能并发。
6、验证各种隔离级别
查看隔离级别 select @@tx_isolation
①验证read uncommitted
set global transaction isolation level read uncommitted;
开启两个窗口
在窗口A start transaction
insert into t_user(id,name) values(1,'jack'); 此时尚未提交结果
在窗口B进行查询 start transaction
select * from t_user
能够查询出结果
②验证read committed
set global transaction isolation level read committed;
窗口A start transaction
insert into t_user(id,name) values(1,'zhangsan')
窗口B start transaction
select * from t_user
此时窗口A未提交,所以在窗口B查不到数据
窗口A commit之后才能在窗口B中查到数据
③验证repeatable read
set global transaction isolation level repeatable read
窗口B start transaction
select * from t_user
窗口A start transaction
insert into t_user(id,name) values(1,'zhangsan')
insert into t_user(id,name) values(2,'lisi')
commit;
窗口B start transaction
select * from t_user
尽管插入了数据,但是并不会在窗口B中查到
④验证serializable
窗口A start transaction
insert into t_user(id,name) values(1,'zhangsan')
insert into t_user(id,name) values(2,'lisi')
窗口B start transaction
select * from t_user
此时A中并未提交结果,在B中进行查询的花会卡住,直到A提交结果