mysql 相关记录

mysql

数据库事务的4个特性:
1.原子性
2.一致性
3.隔离性
4.持久性

首先mysql的存储引擎常用的主要是2种—innodb和myisam,innodb是默认的
主要的区别在于:1.是否支持事物(这就引出一个问题,什么场景下使用哪种存储引擎—由于myisam不支持事物,那么查询势必会比较快,对于允许有部分读写错误的情况下使用会比innodb较好)。2.行级锁和表级锁(对于innodb来说,默认情况下是行级锁,而mysql是通过索引去实现的行级锁,那么如果在索引失效或者没有索引的情况下,行级锁就会变成表级锁,myisam默认是表级锁)。3.是否支持外建。4.个人认为比较重要的一点,磁盘中存储的文件后缀不相同—通过sudo ls /usr/local/mysql/data/gs_zlyy,命令查看某个库下面的文件,myisam在磁盘中是存储为3个文件,分别为frm–表的定义数据,MYD–da ta,MYI–index,从这里可以看出myisam他的index和data是在不同的文件下的,而innodb则是frm和idb文件2中,那么也就是说innodb中index和data是存储在一个文件中的。

现在来说数据库事务的4个特性,其实也就是针对于innodb存储引擎来说的,那么在innodb下存储引擎这一层会存在2个log,分别为undo.log和redo.log,具体什么用处后续再详细的说。对于musql数据库来说,还有一个log也是常常被提起的,也是在server层的bin.log,当数据被删时,可以借助这个日志进行恢复。

现在开始详情的描述4个特性
原子性:一个事物中可能会有多个sql,那么我们就需要去保证,要嘛全部成功,要嘛全部失败,换句话说就是,当有的sql执行失败了,执行成功的sql需要去回滚。这就用到了undo.log,可以这么理解当sql在commit之前,会先在undo.log中先新增一条记录,具体记录的内容也是和sql的写操作相反,比如我的sql是insert的,那么在undo.log中新增的记录就是delete的。undo.log可以理解为回滚日志。

持久性:当事物提交后不会因为其他的任何影响或其他事物的干扰导致持久化后数据的变化或者丢失。这里面就有了一个问题,我们都知道数据库中的数据是存储到磁盘中的,或者数据库就可以理解为持久化数据的一种产品,那么当事物commit后,数据会立马写到磁盘中存储数据的文件吗?这也就引出了前面所说的redo.log这个文件了,这个文件写入的规则和undo.log和bin.log不一样,他们是appead的方式,而redo.log则是循环的方式的去写入数据,可以这么理解,比如redo.log可存储数据的大小是10条数据,当此时进来第11条数据时,他会先把10条数据存储到存储数据的文件也就是idb文件中,再将第11条数据写入进来。这样可以尽量的减少数据的丢失,当然依然会存在丢失的情况,也是当sql commit后,数据到了os的cache中,如何没有到redo.log文件中就服务器挂了,就会丢数据,而mysql中默认的是当commit后,就会将数据存储到os的cache中,并调用系统的命令将os中的数据刷到redo.log文件中。

隔离性:说到隔离性就不得不提起mysql的4种隔离级别了,分别为未提交读,提交读,可重复读,串行化。
未提交读:A事物未提交前,B事物就可以读到A事物修改的数据,造成脏读。还会造成不可重复读和幻读。
提交读:A事物提交前后,B事物2次读到的数据不一致,造成不可重复读,解决了脏读。还会造成幻读。
可重复读:A事物提交前后,B事物2次读到的数据一致,造成幻读,解决不可重复读。
不可重复读和幻读差不多,只是出现的场景不一样。不可重复读发生在读的时候,幻读发生在写的时候。
A事物提交后,比如新增了数据,id用的自增,那么B事物读到的事物是没有A事物提交的数据的,这时也新增的数据,就会报主键重复。
总体来说mysql隔离性就是通过锁来实现的。

一致性:可以说一致性就是mysql事物的终极目的,也就是通过以上3个特性来保证一致性。

索引:
k-v的格式
满足于这种格式的有hash表,树。
索引是建立在磁盘中的,其是否和数据放在一起(同一个文件中)来判断是否是聚簇索引
hash的话查询快,但是会有hahs冲突和不支持范围查询的缺点,在memory搜索引擎中使用。
树:
二叉树—BST—平衡二叉树—红黑二叉树—B树—B+树

二叉树并不是有序的,那么想要提升查询的效率可以使用二分法查找,随之演变而来的BST,查询的时间复杂度是o(logn),但是这会有一种特殊的情况,比如递增或者递减的情况下,BST就退化成了链表,查询的时间复杂度是o(n),那么平衡二叉树也就演变而来,也就是当变成链表的时候,其中的节点会左旋或者右旋,再次转换成2叉树,平衡2叉树规定:叶子结点到根节点最大的长度和最小的长度不能超过1,那么这时就会频繁的发生左旋或者右旋的情况,换句话说就是用insert时慢的效率去弥补了select时快的效率。后续演变出来了红黑二叉树,其规定为:叶子结点到根节点最大的长度和最小的长度之间的倍数不超过2倍,这样insert和select都比较高。这个时候对于树中可以存储的数据的量开始有了要求,2叉树也就是1个节点只会有2个子节点,而每个节点中仅存储一行数据,那么如果数据量大的情况下,要想放入2叉树中的话,这个树的长度将会非常的长。树的长度长了又有什么不好的地方呢?这里需要了解一个io的知识。

数据库是有2个读取的常识的:
1.磁盘预读—内存和磁盘交互数据的时候,有一个最小的逻辑单元,也就是页,或者叫datapage的概念,一般是4k或者8k,每次读取数据都是页的整数倍的读取,对于mysql来说,每次读取的数据的大小是16k。
2.局部性原理—也就是说每次读取数据并不会只读区当前的某一条或某几条数据,而是会读取包括想要的数据的一部分数据,这叫空间局部性,当然还有时间局部性。

聊会前面树的事情,这里假设每个节点之间都要做一次io的交互,那么也就能明白为什么需要控制树的长度,但是依然需要存储大量的数据的话,也就是说二叉树不满足这个要求,那么多叉树是不是可以呢。这个时候就演变来了B-树—一个节点存储多行数据。
这时来比较下B-树和B+树之间的区别:
1.B-树中不管是叶子结点还是非叶子结点均存储数据,而B+树则是只在叶子结点存储数据,换句话说B+树的非叶子结点的大小一定比B-树小。
2.B+树中叶子结点之间有相邻之间的指针指向对方,那么也就是说B+树有2种查询的方式—1)从根节点往下查下,2)从左或者从右查询。
3.B-树种非叶子结点不会有叶子结点种的数据,而B+树是有的。

从以上的区别可以明显看出B+树的优势,也就是说当每次mysql读取数据的大小都是16k的情况下,B-树能读取的结点的个数和B+树来说是完全不能比的,换句话说,B+树中能存储的数据也是B-树完全不能比的。这边还需要聊的话题也就是关于mysql当中的id–主键,id设为自增有2方面的好处:1.insert的时候比大小的效率很高,减少因为比较大小而产生的损耗。2.由于id均为自增,那么在创建索引的时候并不会对于原有的索引结构产生影响,也就是说不会带来索引结构变化或者说上移带来的性能的损耗,当然这是要在以需求为前提的情况下。

回表,索引覆盖,索引下推。

接下来了解mysql innodb的行级锁相关的内容。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值