一、数据库的索引类型介绍一下:
逻辑分类:
a. 主键索引:关系表中定义主键就会自动创建主键索引,每张表的主键索引只能有一个,不能为空并且不可重复。
b. 唯一索引:数据列中不能有重复,可以有空值。一张表中可以有多个唯一索引,但是每个唯一索引只能有一列。
c. 普通索引:可以重复可以空值。
d. 全文索引:可以加快模糊查询,不常用。
物理分类:
a. 聚集索引,数据在物理存储中的顺序跟索引中数据的逻辑顺序相同。比如ID建立索引,id从小到大。在物理存储中,该数据的地址值也是从小到大。一般是表中的主键索引,如果没有主键索引那就以第一个非空的唯一索引作为聚集索引。一张表只能有一个聚集索引。
b. 非聚集索引:物理的存储顺序与逻辑顺序不同。非聚集索引无法定位到数据所在的行,所以只需要扫描两遍索引树。第一遍扫描非聚集索引的索引树。确定该主键ID,根据主键索引寻找相应的数据。
二、什么时候用索引?
以下情况适合用索引。
a. 对于经常查询的列建立索引。
b. 主键上建立索引。
c. 经常需要连接的列需要索引。
d. 经常需要排序的列。
e. 经常需要范围查找的列。
什么情况不适合建立索引。
a. 很少查询的列。
b. 更新很频繁的列。
c. 取值很少的列。
三、索引的底层实现。B树与B+树的区别。
B+树:
a.非叶子节点不存储data,只有叶子节点储存data,非叶子节点储存索引。这样可以放更多索引。
b.叶子节点包含了所有的索引字段。
c.叶子节点用指针连接,方便区间访问。
d.存放同样的数据,B树的层级比B+树要高。因为B+树有冗余索引,相同层级的叶子节点可以更多(更多分叉)。
B树:
a. 叶节点拥有相同的深度,叶节点的指针为空。
b.所有索引不重复。
c. 节点中数据所有从左到右递增排列。
四、MYSQL性能优化
高频访问:
a.分表分库。
b. 增加缓存。
c.增加数据库的索引。
并发优化:
a.主从读写分离。
b.负载均衡。
五、什么是脏读。不可重复读和幻读。
脏读:
脏读是指一个事务在处理过程中读取了一个还没有提交的事务数据。
不可重复读:
对于数据库的某一字段,一个事务多次重新读返回了不同的值。这是由于查询的间隔中,该字段被另一个事务修改并且提交了。
幻读:
读取同一个范围的时候,返回的结果数不一样。这是由于在查询的间隔中,另一事务新增或者删除了数据。
避免不可重复读需要锁行,避免幻读需要锁表。
六、数据库的范式:
第一范式:确保每一列的原子性。
第二范式:在满足了第一范式的前提下,每一列都与主键的所有成员直接相关,而不是主键的一部分。这主要是为了去除数据冗余和修改异常。比如学生,课程,系名,分数。学生和课程作为主键就不行,因为学生决定了系名。
第三范式:在满足第二范式的前提下,为了解决传递函数依赖的问题。每一列数据都与主键直接相关,而不能间接相关。比如学生学号决定院系,院系决定系主任。这里就不是直接相关,应该是系决定系主任。那这里就可以拆成两张表。
BCNF范式。主键之间没有传递以来。
七、数据的锁种类,加锁方式?
MYSQL为例子。
按照类型来看:分为悲观锁和乐观锁。
按照粒度来看:行级锁,页级锁,表级锁。
按照作用来看:共享锁和排他锁。
共享锁:读操作加的锁,别的操作只能加共享锁。不能进行写操作,知道释放所有共享锁。
排他锁:事务对数据加上排他锁之后不能加任何锁。
八、介绍一下乐观锁和悲观锁。
一般的数据库都会支持并发操作,为了避免数据冲突需要对数据上锁。悲观锁假定并发操作一定会数据冲突,在数据开始读的时候就加锁。乐观锁一般假定一般情况下不会发生冲突,只有写操作才会检查数据是否有冲突。
具体的实现上:悲观锁有行级锁和页级锁两种形式。页级锁就是对整张表进行锁定,事务对该表进行访问的时候不允许其他事务进行访问。悲观锁要求整个过程一直与数据库有一条连接,因为上一个事务完成就是下一个事务的开始,这个过程是串行的。
乐观锁的三种实现形式:
a.一种是在执行事务的时候将数据完全拷贝到应用中去,在数据进行更新的时候比较数据库中的数据与新数据,如果两个数据一摸一样的话表示没有冲突可以直接提交。
b.一种是用版本戳来对数据进行标记,每发生一次修改版本号就加一。如果提交的时候版本号一致,那就没有修改。否则就是过期数据需要处理。
c.采用时间戳对数据最后修改时间进行标记,原理与b类似。