数据库相关
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数据库中设置事务的隔离 级别:
-
set [glogal | session] transaction isolation level 隔离级别名称;
-
set tx_isolation=’隔离级别名称;’
3SQL优化 少用in select * 分表 合理使用索引 读写分离
4.