7.B树和B+树的区别
结构特点
- B树:是一种平衡的多路查找树,它的每个节点包含多个关键字和多个子节点指针。B树的叶子节点和非叶子节点都可以存储数据记录。
- B+树:也是一种平衡多路查找树,B+树的非叶子节点只用于索引,即只存储关键字和指向下一层节点的指针,不存储实际的数据记录。所有的数据记录都存储在叶子节点中,并且叶子节点之间通过指针形成一个有序链表。
查询性能对比
- B树:对于单点查询,B树的性能较好。从根节点开始,通过比较关键字,快速定位到目标数据所在的节点。但是,由于数据分布在不同层次的节点,对于范围查询,可能需要在不同层次节点之间频繁切换访问,性能相对B+树较差。
- B+树:单点查询性能和B树类似,通过从根节点向下搜索,能够较快地定位到目标数据所在的叶子节点。在范围查询放没,B+树具有明显优势,因为叶子节点之间的有序链表结构能够方便的获取指定范围内的所有数据,而不需要像B树那样在不同层次间来回查找。
8.为什么数据库使用B+树而不是B树?
1.磁盘I/O操作的优化
- 数据库的操作通常涉及大量的数据存储和读取,而磁盘I/O是数据库性能的一个关键瓶颈.B+树结构更有利于减少磁盘I/O操作。B+树的所有叶子节点形成一个有序链表,这个链表存储了全部数据记录,在进行范围查询的时候,只需要遍历叶子节点链表即可。
- B树因为数据存储在每个节点,所有进行范围查询的时候,需要在不同层次的节点间跳转,导致更多的磁盘I/O操作。例如,假设有一个存储学生成绩的数据库,要查询成绩在 80 - 90 分之间的学生记录。如果使用 B + 树,只要在叶子节点链表中顺序读取符合条件的记录就行;而 B 树可能会因为数据分布在不同层次节点,增加磁盘访问次数。
2.数据存储的高效性
- B+树的非叶子节点只存储索引信息,不存储实际的数据记录,这使得B+树的节点可以存储更多的索引项,从而降低树的高度,意味着查询数据时访问的节点数量减少。
- 因为B树的节点既存储索引,又存储数据,而B+树的节点只存储索引,索引B+树的一个节点可以存储更多索引指针,能有效利用磁盘块空间.
3.数据的顺序访问特性
- B+树的叶子节点之间通过指针连接成有序链表,非常适合顺序访问数据。
- B树节点内部数据是有序的,但节点之间的顺序关系不便于进行大规模的顺序访问。
4.数据更新的稳定性
- 在数据库进行数据插入或删除操作时,B+树结构更加稳定,因为B+树的数据都存储在叶子节点上,当插入和删除数据时,主要影响叶子节点和它相关的指针调整。
- B树进行插入删除操作可能导致非叶子节点的分裂和合并,这种操作的复杂性和影响范围较大。
9.什么是聚簇索引?什么时候用聚簇索引和非聚簇索引?
1.定义
- 聚簇索引是一种对表中数据的物理存储顺序进行重新排序的索引。表中的行数据会按照索引列的值进行重新排序并储存。简单来说,就是索引的顺序和数据的物理存储顺序是一致的。
- 非聚簇索引是独立于数据物理存储顺序的索引。它存储的是索引列的值和指向数据行的指针。
2.何时使用聚簇索引?
- 经常按照某个特定列进行范围查询时。以订单表为例,如果以订单日期作为聚簇索引,那么在查询某个日期范围内的订单(如查询 2024 年 1 月 1 日 - 2024 年 2 月 1 日的订单)时,由于数据是按照订单日期物理排序存储的,数据库只需定位到起始日期对应的记录,然后顺序读取后续记录,直到达到结束日期对应的记录,这样可以大大提高范围查询的效率。
- 需要频繁访问整张表的数据,且数据的访问顺序和某个列的排序顺序一致时。比如一个按时间顺序记录日志的表,经常需要从头到尾读取日志记录。如果以日志时间作为聚簇索引,就可以很好地满足这种访问需求,因为数据在物理存储上已经按照时间顺序排列,顺序读取数据时磁盘 I/O 的效率较高。
3.何时使用非聚簇索引?
- 在频繁通过某个列进行精确查询,但该列不适合作为数据物理存储顺序的依据时。例如,在一个员工信息表中,员工的身份证号码是唯一的,经常需要通过身份证号码查询员工信息。但如果以身份证号码作为聚簇索引,会导致数据按照身份证号码排序存储。此时可以创建身份证号码的非聚簇索引,这样在通过身份证号码查询时,先在非聚簇索引中找到对应的行定位器,再获取数据行,虽然多了一步根据行定位器查找数据的过程,但对于不经常按照身份证号码顺序访问数据的情况,这种方式更灵活。
- 当需要在多个列上创建索引,但不能将所有这些列都作为聚簇索引时。如果一个表中有多个列都需要频繁查询,如一个产品表中有产品编号、产品名称、产品价格等列。可以将产品编号作为聚簇索引(假设产品编号是主要的查询依据,且产品数据通常按照编号顺序管理),然后为产品名称和产品价格创建非聚簇索引,以满足不同的查询需求。
10.非聚簇索引一定会回表查询吗
什么是回表查询?
回表查询是指在使用非聚簇索引查询数据时,由于非聚簇索引只存储了索引列的值和指向数据行的指针(行定位器),如果查询语句需要获取索引列之外其他列的数据,就需要根据这个指针回到数据表中查找相应数据行。
所以这是不一定的,如果查询所需要的列全部都包含在非聚簇索引本身中,就不需要回表查询。
11.什么是数据库事务
定义
数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全部执行成功,要么全部不执行,以确保数据的完整性和一致性。比如在银行转账系统中,a向b转账1000,那么这个操作包含两个步骤:a扣除1000,b增加1000。这两个操作步骤就构成一个事务。
特性
- 原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部完成,要么全部不完成。
- 一致性:事务必须使数据库从一个一致性状态变为另一个一致性状态。比如刚刚银行转账事务,转账前后,要确保银行的总资金不变。
- 隔离性:多个事务并发执行时,一个事务执行不能被其他事务干扰。比如两个转账事务t1(a向b转账),t2(c向d转账),这两个十五同时进行但不会相互影响。
- 持久性:一旦事务体哦叫,他对于数据库的改变时永久性的。即便系统故障。因为数据库系统会通过日志文件,备份恢复等机制来保证这种持久性。
事务的操作
- 开始事务:这是事务的起始点,标志着一系列操作将作为一个事务进行处理。
- 提交事务:如果事务中所有操作都成功完成,就可以提交事务,提交事务后,事务中对数据的修改将永久保存到数据库中。
- 回滚事务:当事务在执行过程中出现错误或者某些操作违反了数据库的约束条件,就需要回滚事务。回滚事务会撤销事务中已经执行的所有操作,将数据库恢复到事务开始之前的状态。
12.什么是脏写?幻读?脏读?不可重复读?
幻读
- 定义:是指在一个事务中,按照某个条件多次读取数据,在两次读取之间,另一个事务插入了新的数据行,导致第一个事务再次读取时,出现了之前没有读取到的"幻影"数据行。
- 产生原因:主要因为事务的隔离级别不够高,在可重复读的隔离级别下,事务可以防止已读取的数据被其他事务修改,但无法防止其他事务插入新的数据。幻读会破坏数据的一致性。
脏读
- 定义:是指一个事务t1读取了另一个事务t2尚未提交的数据,如果另一个事务t2回滚了,那么第一个事务t1读取的数据是无效的,脏的数据。
- 产生原因:还是因为事务的隔离级别不高,比如在读未提交隔离级别下,一个事务可以读取到其他事务未提交的数据。
不可重复读
- 定义:是指在一个事务t1中,对同一个数据进行两次读取,在两次读取之间,有另一个事务t2对该数据进行修改并提交,导致t1两次读取数据不一致。
- 产生原因:主要由于事务的隔离级别不高,在读已提交隔离级别下,一个事务可以读取其他事务已经提交的数据。
脏写
- 定义:是指两个事务,同时对同一个数据进行写操作,并且其中一个事务的写操作覆盖了另一个事务尚未提交的写操作,当另一个事务最终提交时,会导致数据出现不一致的情况。