您的位置 首页 php

10-15k的PHP面试题|Mysql篇

BTree索引的结构和原理

结构实际上是 B+ 树,叶子结点中包含了全部关键字(键值),及指向含有这些关键字记录的指针,叶子结点依关键字的大小自小而大的顺序链接;非终端结点为索引部分,仅含有其子树根结点中最大(或最小)关键字,及指针(B 树的非终节点也包含需要查找的有效信息)。

B+Tree相对于BTree的优势

● B 树的每个节点都包含全部数据,而 B+ 树的节点除了键值和指向下一页的指针以外没有其他数据,由于数据库的节点大小是固定的,因此 B+ 树结点能够存储相对于 B 树更多的键值,树的阶数更大,查询需要的磁盘 IO 次数也更少。

● B+ 的查询效率更加稳定。查询走过的结点数量相同,使得每一个查询的效率都差不多。

● 叶子节点按顺序双向链接,方便范围查询和排序。需要注意的是,叶节点的双向链表并不是 B+ 树的特性,而是 Mysql 索引的具体实现方式。

什么是分区表

分区表(partition by):根据一定规则,将一张表分解成多个部分。从逻辑上看只有一张表,但是底层却是由多个物理分区组成。
分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
分区表中无法使用外键约束。
分区类型:range,list,hash,key

四种隔离级别分别是什么

● 串行化:可避免脏读、不可重复读、幻读

● 可重复读:可避免脏读、不可重复读

● 读已提交:可避免脏读

● 读未提交:任何情况都无法保证

缩写 ACID

不可重复读和幻读的区别

不可重复读是多次读取 同一条 记录,发现该记录中某些列值被修改过。幻读是读取多条记录,发现结果不一致(多或少了)。

如何避免死锁

尽量避免同时锁住多个资源,如果必须这样做,应该保证所有事务都按相同的顺序锁定资源。
Innodb 的锁是逐步获取的,不会一次获取事物所需要的全部锁,所以进行范围操作时也应该保证不同事务按相同顺序锁定资源。
将 innodb_lock_wait_timeout 调小,默认是 50 秒,可以调成 5 秒。

Innodb 在什么情况下会锁表

由于 mysql 的默认隔离级别是可重复读,所以当 sql 使用范围子查询作为锁定语句的条件时就会锁住子查询里的表:

 1
  
 
select * from a where id in (select id from b where id < 6) for update;
  

如果可以的话,将隔离级别改为读已提交即可避免这种情况。 当锁定条件没有使用到索引(进行了全表扫描)时将会锁表。还有一种情况是,当 mysql 的优化器认为即使使用了索引仍然要全表扫描时,就会直接给表加上表锁,因为表锁本身的开销比行锁小。

数据库的范式有哪些

● 第一范式:表中所有字段都是单一属性,不再往下划分。

● 第二范式:表中的非主键必须完全依赖于主键(只有在主键数量大于1时才有可能违反第二范式)

● 第三范式:表中的非主键不可传递依赖于主键。( 学号,系别,系主任 。系主任传递依赖于学号)

● BC范式:表中的每个决定因素都包含候选键。

仓库ID, 存储物品ID, 管理员ID, 数量
[仓库ID, 存储物品ID] 和 [ 管理员ID, 存储物品ID] 都是候选键,但其中
仓库ID 管理员ID 互为决定因素,但它俩都不包含候选键,所以不符合BC范式

缓存表的用途

将大表或多个表中的数据构建在一张表中,当从某些表中频繁读取小部分数据时,缓存表可以提升查询速度,但不保证实时同步,有点类似物化视图。

分库分表算法和应用场景

● 哈希取模算法:提前预估分表的数量,利用 hash 算法得到 hash 值,然后和分表数取余得出表序号。这种分表策略很常见,但后续对表的扩展会比较难做。

● 一致性哈希算法:将多个节点的 hash 值映射到 0 ~ 2^32 范围首尾相接的 hash 环上,再计算存储对象的 hash 值以顺时针方向查找遇到的第一个节点,即为该对象的存储节点。增加和删除节点时,只需要重建受影响的少数节点数据,不会影响到其他节点。采用这种方式,节点的添加和删除都比较容易,但改变节点数量可能会导致数据分配不均,可以采用多个虚拟节点映射到少数物理节点的方式缓解。

● range(field):以某个字段顺序拆分(如 时间),适合日志类的功能。

什么是MVCC

MVCC 就是多版本并发控制,通常情况下的流程是:
● 每行数据都存在一个版本,每次数据更新时都更新该版本

● 修改时Copy出当前版本随意修改,个事务之间无干扰

● 保存时比较版本号,如果成功(commit),则覆盖原记录;失败则(rollback)

就是每行都有版本号,保存时根据版本号决定是否成功。

理想的MVCC难以实现,

Mysql是怎样实现MVCC的

InnoDB 的记录中包含2个隐藏列:
● trx_id:事务 id,在对记录进行改动时将该事务的 id 赋给 trx_id

● roll_pointer:每次对记录进行改动时,都会把旧的版本写入 undo log 中。该列为指向旧版本 undo log 记录的指针。

每个事务都会被分配一个递增ID,当事务进行 快照读 操作时,会生成一个 Read View 用来判断当前事务能够看到哪个版本的数据。

Read View 的结构:

● m_ids:当前系统中活跃的事务id列表

● min_trx_id:最小的活跃事务id

● max_trx_id:分配给下一个事务的事务id

● creator_trx_id:生成该 Read View 的事务id

判断过程:

trx_id=creator_id ,表示当前事务正在访问它自己修改过的记录,该版本可以被当前事务访问

trx_id<min_trx_id ,表示改版本的事务已提交完毕,可访问

trx_id>=max_trx_id ,表示该版本的事务在当前 ReadView 生成之后才开启的,不可访问,通过 roll_pointer 指针找上个版本再次判断

trx_id m_ids 中,表示该版本还是活跃的,不可访问,通过 roll_pointer 指针找上个版本再次判断

trx_id 不在 m_ids 中,表示创建 Read View 时,该版本已提交,可访问

文章来源:智云一二三科技

文章标题:10-15k的PHP面试题|Mysql篇

文章地址:https://www.zhihuclub.com/153535.shtml

关于作者: 智云科技

热门文章

网站地图