索引
-
为什么是B+树?
数据库索引本质上是为了加速数据查找过程,因此一般性的选择有B树和Hash表,而对于仅进行单数据查询的数据库,可以使用Hash索引,使得数据查询的时间复杂度为O(1),但对于一般性的查询来说,因为会涉及到“范围查询”,使用Hash索引并不是一个很好的选择。
使用B树作为数据库索引,相比于二叉搜索树能够更大程度上降低树的高度,减少磁盘IO次数,并且时间复杂度最差为O(logn)。
而在B树的基础上,B+树作为一种更适合作为索引的数据结构出现了。B+树相较于B树主要有两个改进,其一是不再将索引存储在树的内部节点中,转为全部存放在叶子节点中,其二则是建立一条链表,并将所有叶子节点链接到该链表上。这两条改进本质上也是为了加速“范围查询”,当我们定位到本次查询的范围起点后,就可以通过链表加速范围查询,而不是采用B树的中序回溯方式。
注意:操作系统中的页一般大小为4K,而MySQL中的页大小一般为16K。
-
聚簇索引与非聚簇索引
- 聚簇索引:聚簇索引(多为主键)与数据共同存储,辅助索引单独存储<索引内容,主键ID>。若使用辅助索引,则需要经过两次B+树查询,得到条目。
- 非聚簇索引:数据与索引无直接存储关联,无论是使用主键索引还是使用辅助索引都只需要经过一次B+树查询,但辅助索引存在维护成本。
注意:尽管InnoDB会默认将主键设置为聚簇索引,但在某些情况下,使用另一个非主键的值作为聚簇索引会效率更高。而如果不指定主键的话,InnoDB则会隐式定义一个主键来作为聚簇索引。
聚簇索引的优势:
- 索引与数据共同存储,利用磁盘读写的局部性原理(每次读入一页),可以提高查询条目在内存中的命中率,提高查询速度。
- 辅助索引的维护成本更低,不需要因为B+树分裂和磁盘页的分裂而产生更新。
聚簇索引的劣势:
- 聚簇索引的维护成本较高。
- 如果使用隐式定义的默认主键作为聚簇索引则效率甚至可能降低。
数据设计
-
范式理论
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NBRrubJZ-1628259127687)(E:\Pictures\md\QQ图片20210806215009.png)]
事务
-
脏读,不可重复读,幻读
- 脏读:**读无效。**脏读又称无效数据的读出,是指在数据库访问中,事务 A 对一个值做修改,事务 B 读取这个值,但是由于某种原因事务 A 回滚撤销了对这个值得修改,这就导致事务 B 读取到的值是无效数据。
- 不可重复读:读修改。不可重复读即当事务 A 按照查询条件得到了一个结果集,这时事务 B 对事务 A 查询的结果集数据做了修改操作,之后事务 A 为了数据校验继续按照之前的查询条件得到的结果集与前一次查询不同,导致不可重复读取原始数据。
- 幻读:读增加。幻读是指当事务 A 按照查询条件得到了一个结果集,这时事务 B 对事务 A 查询的结果集数据做新增操作,之后事务 A 继续按照之前的查询条件得到的结果集平白无故多了几条数据,好像出现了幻觉一样。
-
事务隔离级别
-
Read uncommitted
读未提交,事务A可以读到事务B未提交的数据。
若读不显式声明则不加锁,此时无法避免脏读,不可重复读,幻读。
-
Read committed
读已提交,事务A只可以读取其他事务已提交的数据。
避免了脏读。
-
Repeatable read
可重复读,保证同一事务多次读取相同数据集返回结果相同。
避免了脏读以及不可重复读。
-
Serializable
串行化,对单一数据的读写全加锁,并发性能很低。
避免了脏读,不可重复读以及幻读。
在MySQL中,默认的事务隔离级别是Repeatable read。
-