美文网首页
简介mysql之视图

简介mysql之视图

作者: 温岭夹糕 | 来源:发表于2021-03-06 18:13 被阅读0次

前言

我们在前文的事务和前文的mysql语句执行流程中都谈到了视图这个概念,其实Mysql有两个视图:
1.view,指查询语句过程中定义的虚拟表
2.指innodb为实现MVCC时使用到的一致性视图,用于支持可重复读和读提交隔离级别的实现。

复习

 CREATE TABLE `t` (
 `id` int(11) NOT NULL, 
`k` int(11) DEFAULT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB;
insert into t(id, k) values(1,1),(2,2);
image.png

很明显A因为视图的关系读到k=1,B因为更新造成的当前读读到3

视图(基于可重复读分析)

视图相当于redis的RDB(快照),innodb每个事务都有唯一的事务id(trx_id),是按照顺序严格递增的

在上文锁中有提及,查看information_schema库中的innodb_trx表获取
先开始的事务获取的事务ID总是小于后开启的事务ID。 只读事务的ID和非只读事务的ID是有些区别的。前者是一个很大的数,后者是一个从1自增的数值。

每次事务更新都会记录回滚日志,生成一个新的数据版本(把trx_id赋值给这个数据版本的事务id,记为row_trx_id),旧的数据版本要保留并在新的版本中能够拿到(数据的版本号不是递增的。) image.png

虚线的三箭头为回滚日志undo log
事务启动时,能够看到已提交的事务结果,执行期间,其他的事务更新对其不可见。

启动时分配一个数据版本,如果一个数据版本是启动后生成就不认,找它的上一个版本(依据undo log),当然自己更新的还是认的(前提是更新成功,修改了数据)

没更新成功的例子:表t有id和c字段,c的值和id值相同

//sessionA执行
begin;
select * from t;
//sessionB
update t set c=c+1;
//sessionA执行
update  t set c=0 where id=c;
select * from t ; //结果与第一次相同
//虽然是当前读但是,这个点已经没有id=c的字段了,这并没有生成新的版本数据 

innodb为每个事务构造了一个数组,用来保存启动时所有启动了但未提交的事务ID

数组里面事务 ID 的最小值记为低水位,当前系统里面已经创建过的事务 ID 的最大值加 1 记为高水位

也就是说比低水位小说明一定是提交了的事务(数据版本可见),比高水位高一定是之后才开始的事务(数据版本不可见),介于之间的包含了未提交的事务和晚于未提交事务开启的事务但是已提交(这个不会出现在数组里) image.png
当介于低水位和高水位之间时,若row_trx_id在数组中,表示这个数据版本是还没提交的事务生成,不可见;反之表示是已经提交的事务生成可见 image.png
如上图,当一个事务的低水位为18时row_trx_id的值小于18的都可见,当它访问这行数据时,从v4=25的数据版本的回滚日志U3得到V3=11 所以该事务的行值为11是可见。 回到刚开始的实验 image.png

1.假设A开始前系统只有一个活跃trx_id=99,
2.假设ABC的trx_id分别为100、101、102(innodb引擎默认一条语句开启一个事务,参考前文mysql语句执行流程日志的二阶段提交),
3.假设三个事务开始前,(1,1)的row_trx_id为90,由很早的事务修改
那么A的视图数组为 [ 99,100 ]
B为 [99,100,101]
C为[99,100,101,102]
4.事务C先提交(1,1)->(1,2),row_trx_id改为102,90为历史版本
5.事务B更新(1,1)->(1,3),row_trx_id为101,102为历史版本,自己查询时102为自己更新的版本,可见
6.事务A查询,事务B未提交,但是101为最新版本,101 比高水位100大不可见,根据undo log往上找,102也大于100不可见,继续往上,直到90版本(1,1)。

小结

1.版本未提交不可见
2.版本已经提交,但是在视图创建后提交,不可见
3.版本已提交,但是在视图创建前提交,可见
这也就是可重复读的隔离级别
事务B的(1,3)没提交不可见,事务C的(1,2)虽提交但是在视图创建之后提交不可见,(1,1)可见
关于事务B能查到(1,3)且是在(1,2)的基础上进行更新是因为当前读,即更新数据都是先读后写,这个读只读当前值,相当于

select k from t where id=1 for update

共享锁和排他锁也是当前读
若进行这个当前读时,事务C还未提交怎么办?

那不就是前文锁中的行锁了吗,当然是事务B被事务C阻塞 image.png

这上面介绍的一系列数据版本控制也就是MVCC机制。
事务的功能就是靠二阶段日志,锁和MVCC三个技术实现的!

相关文章

  • 简介mysql之视图

    前言 我们在前文的事务和前文的mysql语句执行流程中都谈到了视图这个概念,其实Mysql有两个视图:1.view...

  • MySQL之视图

    SQL语言之视图 前言 本章我们将学习MySQL中的视图,视图是数据库中的重要组件,本文将从视图是什么,视图的作用...

  • MySQL之:视图

    视图 VIEW,虚表,保存有实表的查询结果 视图中的数据事实上存储于“基表”中,因此,其修改操作也会针对基表实现;...

  • mysql之视图

    mysql之视图,如何简化查询。视图建议只用于查询就可以了,不要进行增加、删除、修改,因为他所有的修改都是针对源表...

  • 简介Mysql的索引和视图

    索引 索引相当于字典中的查找条件,常用于快速找出某一列中一特定的值,使用索引可以提升查找的速度。 索引的设计原则 ...

  • MySQL之视图VIEW

    本文主要介绍MySQL中的视图, 在什么情况下使用视图。 I、视图介绍 1.1 视图的初步理解 视图是虚拟的表,与...

  • MySQL学习之视图

    一、视图的概念 MySQL从5.0.1版本开始提供视图功能。一种虚拟存在的表,行和列的数据来自定义视图的查询中使用...

  • MySQL基础之STRAIGHT JOIN用法简介

    MySQL基础之STRAIGHT JOIN用法简介 引用mysql官方手册的说法: STRAIGHT_JOIN i...

  • mysql高级:视图、事务、索引

    # mysql高级:视图、事务、索引 * 视图 * 事务 * 索引 * 账户管理 * 主从 ## 1.视图 动态抽...

  • MySQL--索引

    MySQL索引 查看索引 创建索引 创建唯一索引 创建主键索引 删除索引 删除主键 MySQL视图 创建视图 删除...

网友评论

      本文标题:简介mysql之视图

      本文链接:https://www.haomeiwen.com/subject/irhsqltx.html