1.数据库事务隔离级别(脏读、幻读、不可重复读)
一、脏读、不可重复读、幻读
脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
提醒 :
- 不可重复读的重点是修改: 同样的条件,你读取过的数据,再次读取出来发现值不一样了
- 幻读的重点在于新增或者删除: 同样的条件,第 1 次和第 2 次读出来的记录数不一样
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
幻读和不可重复读都是读取了另一条已经提交的事务,不同的是不可重复读的重点是修改,幻读的重点在于新增或者删除。
事务隔离就是为了解决上面提到的脏读、不可重复读、幻读这几个问题。
MySQL数据库为我们提供的四种隔离级别:
- Serializable (串行化):通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。
- Repeatable read (可重复读):MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行,解决了不可重复读的问题。
- Read committed (读已提交):一个事务只能看见已经提交事务所做的改变。可避免脏读的发生。
- Read uncommitted (读未提交):所有事务都可以看到其他未提交事务的执行结果。
2.什么情况下需要建索引?
- 经常用于查询的字段
- 经常用于连接的字段(如外键)建立索引,可以加快连接的速度
- 经常需要排序的字段建立索引,因为索引已经排好序,可以加快排序查询速度
3.什么情况下不建索引?
- where条件中用不到的字段不适合建立索引
- 表记录较少
- 需要经常增删改
- 参与列计算的列不适合建索引
- 区分度不高的字段不适合建立索引,性别等
4.索引的数据结构
索引的数据结构主要有B+树和哈希表,对应的索引分别为B+树索引和哈希索引。InnoDB引擎的索引类型有B+树索引和哈希索引,默认的索引类型为B+树索引。
B+树索引
B+ 树是基于B 树和叶子节点顺序访问指针进行实现,它具有B树的平衡性,并且通过顺序访问指针来提高区间查询的性能。
在 B+ 树中,节点中的 key 从左到右递增排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
进行查找操作时,首先在根节点进行二分查找,找到key所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的数据项。
MySQL 数据库使用最多的索引类型是BTREE索引,底层基于B+树数据结构来实现。
哈希索引
哈希索引是基于哈希表实现的,对于每一行数据,存储引擎会对索引列进行哈希计算得到哈希码,并且哈希算法要尽量保证不同的列值计算出的哈希码值是不同的,将哈希码的值作为哈希表的key值,将指向数据行的指针作为哈希表的value值。这样查找一个数据的时间复杂度就是O(1),一般多用于精确查找。
5.Hash索引和B+树索引的区别?
- 哈希索引不支持排序,因为哈希表是无序的。
- 哈希索引不支持范围查找。
- 哈希索引不支持模糊查询及多列索引的最左前缀匹配。
- 因为哈希表中会存在哈希冲突,所以哈希索引的性能是不稳定的,而B+树索引的性能是相对稳定的,每次查询都是从根节点到叶子节点。
6.索引有什么分类?
-
主键索引:名为primary的唯一非空索引,不允许有空值。
-
唯一索引:索引列中的值必须是唯一的,但是允许为空值。唯一索引和主键索引的区别是:UNIQUE 约束的列可以为null且可以存在多个null值。UNIQUE KEY的用途:唯一标识数据库表中的每条记录,主要是用来防止数据重复插入。创建唯一索引的SQL语句如下:
ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);
-
组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀原则。
-
全文索引:只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引。
7.什么是最左匹配原则?
如果 SQL 语句中用到了组合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个组合索引去进行匹配。当遇到范围查询(>、<、between、like)就会停止匹配,后面的字段不会用到索引。
对(a,b,c)建立索引,查询条件使用 a/ab/abc 会走索引,使用 bc 不会走索引。
对(a,b,c,d)建立索引,查询条件为a = 1 and b = 2 and c > 3 and d = 4
,那么,a,b,c三个字段能用到索引,而d就匹配不到。因为遇到了范围查询!
8.什么是聚集索引?
InnoDB使用表的主键构造主键索引树,同时叶子节点中存放的即为整张表的记录数据。聚集索引叶子节点的存储是逻辑上连续的,使用双向连接,叶子节点按照主键的顺序排序,因此对于主键的排序查找和范围查找速度比较快。
聚集索引的叶子节点就是整张表的行记录。InnoDB 主键使用的是聚簇索引。聚集索引要比非聚集索引查询效率高很多。