面经中刷到的问题:
1.事务的四大特性,具体介绍一下
2.脏读和幻读,不可重复读发生场景与区别
3.介绍一下数据库事务
4.讲一下B+树,为什么使用B+树
5.讲一下主键
6.数据库的四种隔离级别
7.MySQL有哪些索引
8.聚集索引和非聚集索引
四大特性:
- 原子性:事务包含的所有操作要么全部成功要么全部失败回滚
- 一致性:事务操作前后,数据库都是一致性状态
- 隔离性:类似于上锁,防止多个并发事务同一时间访问同一张表
- 持久性:一旦事务操作完成,对于数据库的更改将是永久性的
事务的隔离级别:
- 读未提交:只给写操作上锁,读不上锁。会引起脏读问题,引入读已提交来解决
- 读已提交:写锁(X)读锁(S),不同操作需要分别获取不同的锁。一个数据上有X锁,则不能获取任意锁;一个数据上有S锁,则仍旧可以获取其他S锁。读取了数据之后,不管接下来操作,直接释放S锁。会引起不可重复读问题,引入可重复读来解决
- 可重复读:修改S锁为直到完成事务(一条语句所有的操作)才会释放S锁,发现还有一个问题:幻读,引用串行化解决
- 串行化:事务只能一件一件的进行,不能并发
常见的三大问题:
- 脏读:在A读取数据时,读到了B事务中处理的数据;之后B回滚了,改写数据撤销,但A已经读取到了未撤销的数据
- 不可重复读:同一条事务中,每一次读的数据不一样;A读ab,写c,B写a,A再次写c
- 幻读:A对某一列数据进行了批量更改,但是事后确认时发现一行数据未被更改,因为B在A操作时插入了一行数据
mysql默认级别是可重复读;oracle默认读已提交,还支持串行化
数据库内储存的文件过大,无法都放入内存中,所以无法实现像搜索树这种高效的算法结构。内存每次读取磁盘中的指定地址时,还会以页(4k/8k)为单位读取地址附近的数据
B+树的结构特点:
- 一般为2-4层,每个节点内部的索引都从小到大排列
- 每个中间节点都只储存索引(一般为每个子节点的索引的最大值)
- 叶子节点都在同一层,最多包含阶数个索引以及对应的信息,相互之间形成有序链表
- 查询自顶向下,插入自下向顶
B+树的好处:
- 因为中间节点不储存data,所以单磁盘页内可存放更多索引,比同样的B树更加矮胖,则IO操作次数更少
- 叶子节点都在同一层,稳定的查询时间
- 树的叶子节点构成有序链表,方便范围查询
聚集索引和非聚集索引的区别:聚集索引一般采用主键作为索引条件(默认为第一列unique且不含空的列),叶子节点包含整条数据里的所有信息,一个数据库内只能有一个;非聚集索引中的叶子节点不包含全部的行信息,但是会有bookmark来告诉存储引擎索引对应数据的方法(主键),一个数据库内可存在多个非聚集索引。
主键索引和辅助索引:主要区别在于主键索引中的主键是不可重复的。但请注意如叶子节点储存的是主键以及该主键所记录的含的地址空间,性质为非聚集索引
索引需要注意:尽量取小的索引,提升B+树的性能;注意最左原则
加不加索引?-----主要考虑检索性能与修改性能的平衡;加了索引会提高检索性能但是降低修改性能
加:
- 经常需要搜索的列上(包括主键),提高搜索速度
- 在经常用在连接的列上,加快连接速度
- 在经常需要排序和范围搜索,where的列上,加快速度
不加:
- 很少被查询到的列
- 取值范围很小的列
候选关键字是唯一标识每行数据的属性(集);主属性是候选关键字的成员
数据库三大范式:
- 第一范式:每一行与列对应的单元格都是不可再分的基本元素(二年级一班是可再分组项)
- 第二范式:满足第一范式,非主属性只能对候选关键字形成全部函数依赖,不能形成部分函数依赖,否则拆表 比如:候选关键字为{A, B} A,B-->C and A-->D, 则拆成两个独立的表
- 第三范式:满足第二范式,且非主属性不能对候选关键字形成传递函数依赖,否则拆表 比如:A是候选关键字,A-->B and B-/->A and B-->C,此时需要把表拆为A-->B和B-->C。
不用串行式解决幻读的方法:
- 快照读:保存数据快照,保证单次事务的读不被其他事务所干扰。靠每行数据插入两个冗余位:版本号和回滚指针
- 当前读:除了行锁之外引入了gap锁,在读取行的相互间隙内无法再插入新的行
悲观锁与乐观锁的区别:悲观锁假定会发生冲突,先请求锁再等待或执行;乐观锁假定不会发生冲突,在commit的时候查看版本号或者时间戳,若发生冲突,则回滚事务。
drop:不需要一张表的时候
delete:删除部分数据行时,搭配where
truncate:保留表但是删除所有数据