栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mysql学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql学习笔记

mysql数据库学习笔记

mysql事务相关:数据库的隔离级别:MVCC底层原理数据库存储引擎,以及数据结构innoDB 为什么用B+树结构

mysql事务相关:

一、事务是对数据库执行的一批操作,要么全部成功,要么全部失败(就是回滚)。事务是一个原子操作,是最小执行单位。
事务有4大特性,ACID,即原子性,一致性,隔离性,持久性。

    原子性Atomicity:单个事务,为一个不可分割的最小工作单位,整个事务中所有的操作要么全部commit,要么全部失败rollback。数据记录在undo log中,当前行的历史版本在undo log中。事务的原子性由undo log 来保证。一致性Consistency:数据库总是从一个一致性的状态到另外一个一致性的状态。mysql通过原子性,隔离性,持久性,最终实现数据库的一致性。隔离性lsolation:一个事务所做的修改在最终提交以前,对其他事务是不可见的。也就是说并发的事务之间不能互相干扰。事务的隔离性是由MVCC(多版本并发控制)+锁来实现。持久性durability:一旦事务提交,所做的修改会永久的保存到数据库中。主要由redo log实现。
    总结:对MySQL来说,逻辑备份日志(binlog)、重做日志(redolog)、回滚日志(undolog)、锁技术 + MVCC就是MySQL实现事务的基础。
数据库的隔离级别:

数据库的隔离级别主要有以下四个:
1、读未提交 RU:一个事务还没提交,做的变更就能被其他事务读取到。(别的事务,值的是 同一时间进行crud的操作)事务能够读取到未提交的事务,这是脏读。
2、读已提交 RC:一个事务提交之后(commit),才能被其他事务看到。当一个事务在执行过程中,数据被另一个事务修改,造成本次事务前后读取的信息不一样,这种情况为不可重读。
3、可重复读RR:一个事务执行过程中看到的数据,总是跟整个事务启动时看到的数据是一致的,在此隔离级别下,未提交的变更对其他事务同样不可见。不可重复读是mysql的默认隔离级别,解决脏读,不可重读读的问题(同一个事务多次读取同样的记录结果是一致的),但是有幻读的情况。
幻读:当事务A读取某个范围的数据时候,另一个事务B在这个范围插入了一条数据,事务A再次读取这个范围的数据时,会产生幻读。
4、序列化(串行化)S:串行执行,即同一时刻只能允许一个事务执行,读写都会加锁,读加读锁,写加写锁。当出现读写锁冲突的时候,后访问的事务要等前一个事务执行完才可。
最高的隔级别,完全服从ACID的隔离级别。所有的事务一次逐个执行,事务直接不会产生干扰。改级别防止脏读,幻读,不可重复读等问题。

总结:事务的隔离级别基于锁机制和MVCC(并发调度)。其中并发调度使用的是MVCC(多版本并发控制)通过保存修改的旧版本的信息来支持并发一致性和回滚等特性。
因为事务的隔离级别越低,事务请求的锁越少,所以大部分数据的隔离级别是读已提交READ-COMMITED;
但是要知道InnoDB存储引擎的默认隔离级别是可重复读REPEATABLE-READ,并不会有任何性能损失。

MVCC底层原理

MVCC多版本并发控制,是用来在数据库中控制并发的方法,实现对数据库并发访问用的。mysql中,mvcc只有在读已提交,可重复读两个事务隔离级别下有效。
主要实现:undo log中的版本链+readView一致性试图。
MVCC就是在多个事务同时存在时,select语句找到具体是版本链上的哪个版本,然后在找到的版本上返回其中所记录的数据过程。
一、mysql中,会默认在我们的表后面添加三个隐藏字段:
1、db_row_id:行id。因为mysql的B+数索引要求每个表必须要有一个主键。

首先需要知道的是,在MySQL中,会默认为我们的表后面添加三个隐藏字段:
1、db_row_id:行id。mysql的索引数据结构为B+数,要求每个表必须要有一个主键。如果没有设置主键,会自动寻找第一个不包含NULL值的唯一索引作为主键。如果未找到,就会在这个DB_ROW_ID上自动生成一个唯一值,以此来当作主键(跟MVCC无关)
2、db_tax_id:事务id,记录的是当前事务所在的insert或者update语句操作的事务Id(delete语句是update的特殊执行)
3、db_roll_ptr:回滚指针,通过它可以将不同的版本串联起来,形成版本链。
DB_ROLL_PTR:回滚指针,通过它可以将不同的版本串联起来,形成版本链。相当于链表的next指针。
二、ReadView一致性试图
主要由两部分组成,

ReadView
ReadView一致性视图主要是由两部分组成:所有当前未提交事务的数据+当前创建的已经提交的最大事务ID。
当执行select语句的时候会创建ReadView,在读已提交和可重复度两个事务不同的隔离级别下,生产ReadView的策略不同:
读已提交隔离级别:每执行一次select语句会生成一份readView。
可重复读:只会在第一次select语句只从的时候生成一份。
三、版本链
所有版本的数据都只会存一份,然后通过回滚指针连接起来,之后就是通过一定的规则找到具体是哪个版本上的数据就行了。假设现在有一张account表,其中有id和name两个字段,那么版本链的示意图如下:

RR隔离级别下,幻读问题是怎么解决的:
主要依靠MVCC(一致性快照)+间隙锁
手动加锁阻塞另一个线程的insert(for update),也就是通过innodb的next-key算法(间隙锁)

数据库存储引擎,以及数据结构

mysql的存储引擎有十几种,比如 innoDB,myisam,Memory,Merge、Archive、Federated、CSV、BLACKHOLE 等。常用的存储引擎有innodb,myisam。
一、innoDB
innoDB是mysql5.5之后版本的默认存储引擎。相比与myisam强调性能,侧重于支持事务,以及外键等。
1、支持事务,innoDB的默认隔离级别为可重复读,通过MVCC(多版本并发控制)+锁来实现。
2、使用的锁颗粒度默认是行锁,可以支持更高的并发;也支持表锁,不支持页锁。
3、支持外键约束,外键约束增加了表之间的耦合性,降低查询速度。(当然开发中用的比较少,一般在业务层面控制)
4、innoDB的自动提交是默认打开的(autocommit)
5、innoDB的主键范围更大,最大是myisam的2倍。主键可以通过auto_increment的方法自增长。
6、配合一些热备工具可以支持在线热备份;6、在InnoDB中存在着缓冲管理,通过缓冲池(innodb_buffer_size),可以将部分索引和数据缓存起来,加快查询的速度;
7、innoDB存储引擎下的表,数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一起,都在B+数的叶子节点上存储。
7、对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+树的叶子节点上;
8、innoDB 在delete from 删表时,不会重建立表,而是一行一行的删除。底层是给行数据的is_delete字段加了删除标记。实际不会直接清空磁盘内容。这样做也有一个好处就是innoDB能通过flashback等插件快速找回误删除的数据。但是有个坏处,就是删除一张大表后发现磁盘空间不降反增(因为增加了事务日志等信息)。
9、innoDB有两种方式存储表和索引:
共享表空间存储:所有的表和索引存放在同一个表空间中。
多表空间存储:表结构放在.frm文件,数据和索引放在.ibd文件中。分区表的话,每个分区对应单独的.ibd文件。
总结:InnoDB,最大的优势在于支持事务。
二、myisam
1、不持支事务,不支持锁。所以读写的效果比innoDB高很多。
使用场景:日志记录,调查统计表等。
2、Myisam的索引和数据是分开存储的,索引是由压缩的,内存使用率更高,能加载更多索引。innoDB索引和数据都在在叶子节点存储,没有压缩,所以innoDB比Myisam数据文件大。
3、每张Myisam表在磁盘上对应三个文件:
.frm文件:存储表的定义数据
.MYD文件:存放表具体记录的数据
.MYI文件:存储索引
3、select count() 和order by这两个比较频繁的操作,innoDB会锁表,(innoDB的行锁是where 条件加主键才有效,非主键还是会锁表。)
4、导表数据Myisam比较方便,只要复制对应表的三个文件(frm,myd,myi),重启数据库启动就行。而Innodb需要导出.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。
5、没有where的count(
)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,表的总行数row存储在磁盘上,直接返回总行数。但当 count(*) 语句包含 where条件时,两种引擎的操作流程是一样的。
6、DELETE FROM table时,MyISAM会先将表结构备份到一张虚拟表中,然后执行drop,最后根据备份重建该表。这是我使用这两个引擎时让我感觉区分最明显的特性之一。

平时开发中你是怎么选择这两个引擎的?
是否要支持事务;
读多写少可以倾向 MyISAM,如果写比较频繁就用InnoDB。
系统奔溃后,MyISAM恢复起来更困难,我之前出现过表损坏情况,能否接受,不能接受选 InnoDB;
不知道用什么就用InnoDB。

innoDB 为什么用B+树结构

索引:关系型数据库中,索引是一种单独的,物理的对数据库表中的一列或者多列的值进行排序一种存储结构,是某个表中一列或者多列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。mysql5.5以后innoDB存储引擎使用的索引的数据结构是B+树。
B+Tree可以对<,<=,=,>,>=,BETWEEN,IN,以及不以通配符开始的LIKE使用索引。(MySQL5.5后)

答案:索引是为了加快数据访问,索引底层实现原理是B+数,为啥不用B数,hash表,二叉数,红黑数,AVL数,因为:AVL树和红黑树基本都是存储在内存中才会使用的数据结构。在大规模数据数据存储的时候,显然不能将全部数据全部加载进内存,因此如果采用红黑树,就会造成频繁IO,效率低下。
B tree的两个明显特点:1、树内存储数据2、叶子节点上无链表
B+ tree的两个明显特点:1、数据只出现在叶子节点2、所有叶子节点增加了一个链指针
数据库索引采用B+ tree的主要原因是B Tree在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。正是为了解决这个问题,B+ tree应运而生。B+ tree只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,如果使用B Tree,则需要做局部的中序遍历,可能要跨层访问,效率太慢。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/749754.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号