数据库面试知识点

  1. 什么是数据库索引:
    MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据/的数据结构。

  2. 索引的类型:
    MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等

  3. 为什么使用数据库索引能提高效率:

    • 数据索引的存储是有序的,建索引时,会根据索引key进行排序(B+树的叶子节点就是排好序的结果)
    • 在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
    • 极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)
  4. 为什么用自增列作为主键

    1. 如果我们设定了主键(PRIMARY KEY),那么InnoDB(数据库)引擎会选择主键作为聚集索引;
      • 如果没有显式定义索引那么InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引。
      • 如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID(行id)作为隐含的聚集索引(ROWID随着行记录的写入而主键 递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)
    2. 每当有一条新的记录插入时(插入B树),MySQL会根据其主键将其插入适当的节点和位置;
      • 如果是递增的主键,新的数据直接插入B树末尾,减少了B树维护的开销代价;
      • 如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点),(B树是专门的磁盘存储数据结构)
  5. 哈希索引的优势

    • 哈希索引采用的是哈希表实现,索引再没有哈希冲突的情况下查询效率为1;
  6. 哈希索引不适用场景

    • 不支持范围查询
    • 不支持索引完成排序
    • 不支持联合索引的最左前缀匹配规则
  7. B树和B+树的区别

    1. B树,每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为nul,叶子结点不包含任何关键字信息。
    2. B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接
      所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。(而B 树的非终节点也包含需要查找的有效信息)
  8. 为什么B+树比B树更加适合实际应用中操作系统的文件索引和数据库索引

    • B树每个节点都存储key和date,导致一页所存储的数据较少,加深了树的深度,增加了IO次数;
    • B+tree的查询效率更加稳定。
      由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
  9. 什么情况下应不建或少建索引?

    • 表数据太少
    • 经常增删改的表
    • 数据重复且分布平均的表字段
    • 经常和主字段一块查询但主字段索引值比较多的表字段;
  10. 什么是表分区(物理上多个分开了)

    • 表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
  11. 表分区和分表的区别

    • 分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。
      分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。
  12. 表分区的好处

    • 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
    • 增强可用性:如果表的某个分区出现故障,表的其他分区的数据仍然可用;
    • 维护方便:如果表的某个分区出现故障,只需修复出故障的分区;
    • 均衡 I/O:可以把不同的分区映射到磁盘以均衡 I/O,改善整个系统性能;
    • 优化查询。在where语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及sum和count语句时,也可以在多个分区上并行处理,最后汇总结果。
  13. 分区表的限制因素
    1、一个表最多只能有1024个分区
    2、MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。
    3、如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
    4、分区表中无法使用外键约束
    5、MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。

  14. 如何判断当前MySQL是否支持分区
    命令:show variables like ‘%partition%’ 运行结果:have_partintioning 的值为YES,表示支持分区。

  15. MySQL支持的分区类型有哪些
    RANGE分区:这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区
    LIST分区:这种模式允许系统通过预定义的列表的值来对数据进行分割。按照List中的值分区,与RANGE的区别是,range分区的区间范围值是连续的。
    HASH分区 :这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。
    **KEY分区 **:上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。

  16. 四种事务隔离级别

    • Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
    • Repeatable read (可重复读):可避免脏读、不可重复读的发生。
    • Read committed (读已提交):可避免脏读的发生。
    • Read uncommitted (读未提交):最低级别,任何情况都无法保证。
  17. 关于MVCC

  18. 在MVCC并发控制中,读操作可以分两类

  19. 行级锁定的优点
    1、当在许多线程中访问不同的行时只存在少量锁定冲突。
    2、回滚时只有少量的更改
    3、可以长时间锁定单一的行。

  20. 行级锁定的缺点:
    比页级或表级锁定占用更多的内存。
    当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。
    如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多。
    用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。

  21. MySQL优化

  22. key和index的区别

  23. MySQL中MyISAM和InnoDB的区别
    区别:
    1、InnoDB支持事务,MyISAM不支持
    对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
    2、InnoDB支持外键,而MyISAM不支持。
    对一个包含外键的InnoDB表转为MYISAM会失败;
    3、InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。
    但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此主键不应该过大,因为主键太大,其他索引也都会很大。
    而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
    4、InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
    5、Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;
    如何选择:
    是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
    如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB
    系统奔溃后,MyISAM恢复起来更困难,能否接受;
    MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差
    参考:
    MyISAM索引实现
    InnoDB索引实现

你可能感兴趣的:(数据库面试知识点)