数据库 索引,事务隔离,优化,联合索引,最左匹配原则,索引失效,聚类/非聚类索引,数据库锁,设计数据库表,索引数据结构
索引:
·什么是索引:索引是一个用于快速查询和检索数据的数据结构,它存储了一个表中特定列的值和它的物理地址的值。
·索引是什么数据结构:B树、B+数、哈希表。 其中当大量需求为单表记录查询时再使用哈希表,其余大部分时候都使用B-TREE。 (B树、B+树的数据结构) B和B+的区别、和hash的区别
·聚集索引和非聚集索引: 聚集索引指的是索引和数据放在一起的索引。当搜索到索引时对应的data就是需要的数据。主键索引属于聚集索引。 非聚集索引指索引和数据分开放的索引。当检索到索引时对应的data是另外一个索引例如数据的指针或主键。二级索引属于非聚集索引。 两者优缺点: 聚:优点:查询非常快,因为B+树叶子节点是有序的,定位到索引就相当于找到了数据。 缺点:1.依赖于有序的数据 2.更新代价大。 非:优点:更新代价相对小。 缺点:1.依赖于有序的数据 2.可能需要二次查询(找到了指针/主键还需要去表里查对应的数据)
·覆盖索引:当要查询的字段正好是索引的字段时,称为覆盖索引。如一条SQL要查name,而name字段正好建了索引,那么直接根据这个索引就可以查到name了。
·联合索引:由多列属性组成的索引。
·最左匹配原则:如果查询条件匹配索引的最左列开始并且不跳过索引中的列,那么可以成功查询。 如联合索引(name,city,age),如果查询name/name and city/name and city and age成功,而如果查询city等就不成功。
·索引类型: 主键索引、辅助索引/二次索引(叶子节点存储的data是主键,唯一索引、普通索引、前缀索引都属于这个)
·索引失效:
数据库事务隔离
·事务ACID: 原子性:动作要么全都完成,要么都不完成 一致性:多个事务读取同一个数据结果应是一样的 隔离性:并发时,一个事务不受其他事务的影响 持久性:一个事务被提交后,其对数据库的影响应该是持久的,即使数据库发生故障都不应该对其有任何影响。
·并发事务带来的问题: 脏读:一个事务在修改了数据但还没有提交时,另一个事务访问了数据,但得到的是修改之前的数据,而这个就是“脏数据” 丢失修改:一个事务读取数据时,另一个事务也访问了该数据,那么如果第一个事务修改了数据后,第二个事务也修改了数据,那么就会丢失第一个事务的修改。 不可重复读:指在一个事务内两次读到的数据不一样。一个事务多次读取同一事务,在这个事务还没有结束时,另一个事务也访问并修改了该数据,那么第一个事务再次访问这个数据时就会得到不同的数据 幻读:第一个事务读取了几行数据,这时第二个事务访问并添加/删除了几行数据,在随后的查询中,第一个事务就会发现数据中多/少了几条原本不存在的数据。 (不可重复读和幻读的区别在于,不可是修改了该数据,幻读是新增/删除了原本的数据)
·事务隔离级别 读取未提交:一个事物可以看到其他事物没有提交的新插入的记录和对已有数据的更新。可能会导致脏读、幻读、不可重复读 读取已提交:一个事物可以看到其他事物已提交的新插入的记录和对已有数据的更新。可防止脏读,但可能导致不可重复读和幻读 可重复读:一个事物可以看到其他事物已提交的新插入的记录,但看不到其他事物已提交的对已有数据的更新。可防止脏读、不可重复读,但阻止不了幻读。 可串行化:最高安全级别。对于访问同一数据,一个事务在进行操作时,其它事务只能等待直到第一个事务结束后才能正常运行。相当于以串行化方式运行。 MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。
数据库优化(待定)
1.限定数据范围:比如指定只能查询一个月内的数据 2.读写分离:主库用来写,从库用来读 3.垂直分区:把一个表很多列拆分成不同的表。 优点:使行数据变小,在查询时减少读取的block数,减少I/O次数 缺点:主键会出现冗余,需要管理冗余列,它也会让事务变得复杂。 4.水平分区:横向拆分,把一张表数据分片,把每一段的数据分散到不同的表中。
数据库锁、MVCC(待定)
悲观锁:当事务需要对资源进行操作时,先获得资源对应的锁保证其他事务不会访问该资源后,再对数据进行操作。(这个锁是数据库自带的各种锁)但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。
乐观锁:乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。 相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。