数据库相关

1.索引、B树、B+树

MySQL的MyISAM、InnoDB引擎默认均使用B+树索引。

唯一索引:不允许其中任何两行具有相同值的索引 。

主键索引:可以认为是特殊的唯一索引,仅利用主键建立的索引

单一索引:任何一个单一数据项建立的索引 

复合索引:多个数据项建立的索引 

聚簇索引:利用主键建立的索引,其物理存放顺序与主键顺序一致。因为数据只有一个物理存放顺序,所以一个表只有一个聚簇索引。 

非聚簇索引(二级索引,辅助索引):除了聚簇索引之外,其余所有的索引都是非聚簇索引 

覆盖索引:一个索引包含(覆盖)所要查询的字段的值,注意覆盖索引与具体的查询有关 

索引为了快速检索数据。

B+ Tree索引(MySQL,SQL Server,Oracle) 

 

 

 

  • 修改key与子树的组织逻辑,将索引访问都落到叶子节点
  • 按顺序将叶子节点串起来(方便范围查询)

B+ Tree索引优点
  ①.全值匹配:指的是和索引中所有列进行匹配。假设以(姓,名,出生日期)三个数据项建立复合索引,那么可以查找姓名为张三,出生日期在2000-12-12的人
  ②.匹配最左前缀:假设以(姓,名,出生日期)三个数据项建立复合索引,可以查找所有姓张的人
  ③.匹配列前缀:假设有姓为司徒,司马的人,我们也可以查找第一列的前缀部分,如查找所有以司开头的姓的人
  ④.匹配范围值:可以查找所有在李和张之间的姓的人,注意范围查询只在复合索引的优先排序的第一列。(假设姓名按照拼音排序)
  ⑤.精确匹配前面列并范围匹配后一列:可以查找姓李并出生日期在2000-12-12之后的人或姓名为张三并出生日期在2000-12-12之后的人,注意范围第一个范围查询后面的列无法再使用索引查询
  ⑥.只访问索引的查询:即查询只需访问索引,而无需访问数据行。(此时应想到索引中的覆盖索引)

B+ Tree索引缺点
  ①.如果不是按照索引的最左列开始查找,则无法使用索引。如无法查找名为龙的人,也无法查找在2000-12-12之后出生的人,当然也无法查找姓中以龙结尾的人(注意为和含有的区别)
  ②.不能跳过索引中的列:无法查找姓李并在2000-12-12之后出生的人
  ③.如果查询中包括某个列的范围查询,则其右边所有列都无法使用索引优化查询
 B Tree索引 

 

B树的深度维持在约log(ceil(m/2))(n)~logm(n)之间,大大降低树高。

 

磁盘IO次数才是更大的影响因素。B树与AVL的时间复杂度是相同的,但由于B树的层数少,磁盘IO次数少,实践中B树的性能要优于AVL等二叉树。

B树对局部性原理非常友好

哈希索引:(MySQL,Oracle)

缺点

支持等值查询;

哈希冲突较多时,维护操作的代价会变大;

哈希索引也不支持部分索引列查询,因为哈希索引始终是使用索引列的全部数据进行哈希计算的。 

.哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序和范围查询 ;

哈希索引只包含哈希值和行指针,所以不能用索引中的值来避免读取行

优点

快速查询:参与索引的字段只要进行Hash运算之后就可以快速定位到该记录,时间复杂度约为1

2.事务的隔离级别

Read uncommitted一个事务可以读取另一个未提交事务的数据。

产生脏读问题

Read committed 解决脏读 一个事务要等另一个事务提交后才能读取数据

产生不可重复读问题

Repeatable read 在开始读取数据(事务开启)时,不再允许修改操作 。解决不可重复读问题

可能还会有幻读问题 幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

Serializable 序列化  解决幻读问题

在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

 一个更新事务更新一条数据时,另一个读取事务读取了还没提交的更新,这种情况下会出现读取到脏数据。
 一个读取事务读取一条数据时,另一个更新事务修改了这条数据,这时就会出现不可重复的读取。
一个读取事务读取时,另一个插入事务(注意此处时插入)插入了一条新数据,这样就可能多读出一条数据,出现幻读。
修改时允许读取(脏读)

读取时允许修改(不可重复读)
读取时允许插入(幻读)

Mysql的默认隔离级别是Repeatable read。

大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。

如何解决幻读

forupdate

间隙锁

nextkeylock

InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题

在MySQL数据库中查看当前事务的隔离级别: select @@tx_isolation;

在MySQL数据库中设置事务的隔离 级别:   

  1. set  [glogal | session]  transaction isolation level 隔离级别名称;
  2.  
     set tx_isolation=’隔离级别名称;’

 

3SQL优化 少用in  select * 分表 合理使用索引  读写分离 

4.

InnoDB是一个事务型的存储引擎,有行级锁定和外键约束。

posted @ 2019-09-17 20:35  不喜欢吃胡萝卜  阅读(144)  评论(0编辑  收藏  举报