Mysql 详解

Posted 跟着卓仔一起成长

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 详解相关的知识,希望对你有一定的参考价值。

今天开始卓仔要复习各个组件的基本原理和使用场景等知识了, 先学习mysql、redis、nginx、kafka等。 非常常用面试也经常问的组件。


1
事物!



数据库事务:简单的说事务就是一组原子性的SQL语句。可以将这组语句理解成一个工作单元,要么全部执行要么都不执行。默认MySQL中自动提交时开启的(start transaction)事务的ACID特性如下:


1)原子性(Atomicity): 


一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。


2)一致性(Consistency):


 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。(比如:A向B转账,不可能A扣了钱,B却没有收到)


3)隔离性(Isolation):一个事务所做的修改在提交之前对其它事务是不可见的。两个以上的事务不会出现交错执行的状态.因为这样可能会导致数据不一致。

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。(比u人:A正在从一张银行卡里面取钱,在A取钱的过程中,B不能向这张银行卡打钱)


4)持久性(Durability):一旦事务提交,其所做的修改便会永久保存在数据库中。



事务的并发问题


  1、脏读:指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。


  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。


   3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。


  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表


事务的隔离级别如下:


READ UNCOMMITTED(读未提交):事务中的修改即使未提交也是对其它事务可见


READ COMMITTED(读提交):事务提交后所做的修改才会被另一个事务看见,可能产生一个事务中两次查询的结果不同。


REPEATABLE READ(可重复读):只有当前事务提交才能看见另一个事务的修改结果。解决一个事务中两次查询的结果不同的题。


SERIALIZABLE(串行化):只有一个事务提交之后才会执行另一个事务。


mysql默认的事务隔离级别为repeatable-read 可重读




2
InnoDB和MyISAM引擎!



区别:

1. MyISAM只支持表锁、InnoDB支持表级锁和行级锁

2. MyISAM存储引擎不支持事务,它强调的是高性能的查询,适合读多写少、原子性要求低的情形。


对于InnoDB存储引擎则提供了较为完善的事务支持,一共支持4个等级的事务隔离级别:未提交读、已提交读、可重复读、可序列化。


3. 主键

MyISAM可以支持没有主键的表存在。


InnoDB必须设置主键,如果用户没有指定主键,那么会在表文件中设置一个6字节长的ROWID,并以此为主键。之所以这么做是因为和InnoDB的表文件结构密切相关,待会我们会提到。


4、自增列(自增主键)

对于InnoDB的自增列,InnoDB规定必须包含只有该字段的索引。

如果是MyISAM的自增列,则可以将该字段与其他字段组成联合索引。


5. InnoDB支持外键,MyISAM不支持外键。


存储结构和索引
1)MyISAM存储引擎

MyISAM将一张表的结构和内容分为三个文件:


1、表结构文件,后缀名为frm
2、索引文件,后缀名为MYI
3、数据文件,后缀名为MYD


索引文件保存记录所在的数据文件的位置,通过读取索引文件获取到位置信息后,再通过读取数据文件快速取得数据


Mysql 详解


所以MyISAM中是每个索引一个文件存储。


2)InnoDB存储引擎


相比MyISAM,InnoDB只有两个文件:

1、表结构文件,后缀名为frm

2、数据、索引文件,后缀名为ibd


虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。




是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。




是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。



1.聚集索引


聚集索引是按每张表的主键构造的一颗B+树,并且叶节点中存放着整张表的行记录数据,因此也让聚集索引的节点成为数据页,这个特性决定了索引组织表中数据也是索引的一部分。由于实际的数据页只能按照一颗B+树进行排序,所以每张表只能拥有一个聚集索引。查询优化器非常倾向于采用聚集索引,因为其直接存储行数据,所以主键的排序查询和范围查找速度非常快。

不是物理上的连续,而是逻辑上的,不过在刚开始时数据是顺序插入的所以是物理上的连续,随着数据增删,物理上不再连续。


2.辅助索引


辅助索引页级别不包含行的全部数据。叶节点除了包含键值以外,每个叶级别中的索引行中还包含了一个书签,该书签用来告诉InnoDB哪里可以找到与索引相对应的行数据。其中存的就是聚集索引的键。


辅助索引的存在并不影响数据在聚集索引的结构组织。InnoDB会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后通过主键索引找到一个完整的行记录。当然如果只是需要辅助索引的值和主键索引的值,那么只需要查找辅助索引就可以查询出索要的数据,就不用再去查主键索引了。




联合索引


MySQL中的索引可以以一定顺序引用多个列,这种索引叫做联合索引,一般的,一个联合索引是一个有序元组<a1, a2, …, an>,其中各个元素均为数据表的一列。单列索引可以看成联合索引元素数为1的特例。


条件按照 a1,a2...an 的顺序索引才会生效。例如索引3列(a1,a2,a3)


  (1)....where   a1=1 and a2=1 and a3=1    三个列的索引都生效。


  (2)....where   a1=1     a1索引都生效。



  (3)....where   a1=1 and a3=1   a1索引都生效,a3无法生效


   (4)....where   a1=1 and a2 like ’po%‘    索引生效 


(5)范围列可以用到索引(必须是最左前缀),但是范围列后面的列无法用到索引。同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引。


....where   a1<10 and a2 like ’po%‘   a2索引无效 


(6)同时,用了“between”并不意味着就是范围查询。


....where   a1 BETWEEN 1AND  12  AND a2=1 AND a3 BETWEEN 4 AND 8;


看起来是用了两个范围查询,但作用于a1 上的“BETWEEN”实际上相当于“IN”,也就是说a1实际是多值精确匹配。可以看到这个查询用到了索引全部三个列。因此在MySQL中要谨慎地区分多值匹配和范围匹配,否则会对MySQL的行为产生困惑。



使用场景

1、如果应用程序对数据的一致性要求比较高,那么需要选择InnoDB,因为InnoDB支持事务和外键
2、以读操作为主的业务,适合使用MyISAM。对于读多写多的业务,适合使用InnoDB。


1)MyISAM存储引擎



以上是关于Mysql 详解的主要内容,如果未能解决你的问题,请参考以下文章

MySQL存储过程详解

Mysql加锁过程详解-innodb下的记录锁,间隙锁,next-key锁

Mysql加锁过程详解-innodb下的记录锁,间隙锁,next-key锁

MySQL进阶MySQL事务详解

mysql索引数据结构详解---mysql详解

mysql执行计划与索引详解---mysql详解