数据库

作者: 旺旺大仙贝 | 来源:发表于2018-08-21 20:32 被阅读0次

    [toc]

    索引

    索引优化是对查询性能优化的最有效手段。是存储引擎能够快速定位记录的秘密武器。

    索引的数据结构

    InnoDB存储引擎大多情况下使用B+树建立索引,这是关系型数据库中查找最为常用和有效的索引,但是B+树索引并不能找到一个给定键对应的具体值,它只能找到数据对应的页,数据库把整个页读入到内存中,并在内存中查找具体的数据行。
    B+树是平衡树,查找任意节点消耗的时间相同,因此比较次数就是B+树的高度。

    聚集索引和辅助索引

    数据库中的B+树索引可以分为聚集索引(clustered index)和辅助索引(secondary index)。聚集索引存放一条记录的全部信息,辅助索引只包含索引列和一个用于查找对应行记录的书签。
    聚集索引:正常的表应该有且仅有一个聚集索引(绝大多数情况下是主键),表中的所有记录数据都是按照聚集索引的顺序存放的。
    辅助索引:叶节点不包含行记录的全部数据,仅包含索引中的所有键和一个用于查找对应行记录的书签,辅助索引只用于加速数据的查找。

    锁的出现是为了处理并发问题,数据库是一个多用户的资源,当出现并发的时候就会出现例如读“脏”数据,修改丢失等问题。数据库并发需要使用事务控制,事务并发又需要锁来控制。

    乐观锁和悲观锁

    乐观锁和悲观锁都是并发控制的机制,在原理上有本质区别
    乐观锁:是一种思想,并不是一种真正的锁。读取数据时不担心被修改,在更新时判断是否被修改过,没被修改就更新,否则重试。
    悲观锁:一种真正的锁。在获取资源前就对资源加锁,确保同一时刻只有有限的线程能够访问该资源,其他想获取的操作都会进入等待状态。
    乐观锁适用于读操作较多的场景,不会存在死锁的问题,但是冲突频繁和重试成本高时还是推荐使用悲观锁。

    共享锁和互斥锁

    对数据的操作只有两种:读和写,针对这两种InnoDB实现了标准的行级锁。只对某一个数据加锁。
    共享锁(读锁):允许事务对一条行数据进行读取。之间兼容
    互斥锁(写锁):允许事务对一条行数据进行删除和更新。与其他任意锁都不兼容
    思考WHY这么设计:因为我们可以对数据库并行读,串行写。这样不会发生线程竞争,实现线程安全。

    意向锁

    意向锁属于表级锁。对当前操作的整张表加锁。
    意向共享锁:事务想在获得表中某些记录的共享锁,需要在表上先加意向共享锁
    意向互斥锁:事务想在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

    锁的算法

    锁是如何添加到对应的数据行上的。
    Record Lock(记录锁):加到索引记录上的锁。
    Gap Lock(间隙锁):对索引记录中的一段连续区域的锁。SELECT * FROM ... FOR UPDATE
    Next-Key Lock:记录锁和间隙锁的结合,解决幻读的问题。

    事务

    事务四大特性

    Automatic(原子性):一个事务要么完全发生,要么完全不发生
    Consistency(一致性):事务把数据库一个一致状态变为另一个一致状态
    Isolation(隔离性):在一个事务提交之前,其他事务察觉不到事务的影响
    Durability(持久性):一旦事务提交,将是永久被保存的

    事务四种隔离级别

    • Read Uncommitted (读未提交):查询时是不加锁,更新时加行级共享锁,可能读到未提交的行(Dirty Read)
    • Read Committed(读已提交):查询是只对记录加记录锁,不会在记录之间加间隙锁,所以允许新纪录插入到被锁定记录的附近。多次查询时可能得到不同结果(Non-Repeated Read)。
    • Repeated Read(可重复读):查询时加行级共享锁,多次读取同一范围的数据会返回第一次查询的快照,不会返回不同的数据行,可能会发生幻读
    • Serializable(串行化):读取时加表级共享锁,更新时加表级排它锁。

    四种隔离级别下的问题

    脏读:一个事务中,读取了其他事务未提交的数据
    不可重复读:一个事务中,同一行记录被访问两次得到不同结果
    幻读:在一个事务中,同一个范围内的记录被读取时,其他事务向这个范围添加了新的记录

    相关文章

      网友评论

          本文标题:数据库

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