MySQL常见面试题

144 阅读5分钟

存储引擎

  • InnoDB
    • 支持事务
    • 支持行级锁
    • 支持外键

对数据准确性要求比较高,插入数据比较多的情况下

  • MyISAM
    • 不支持事务
    • 支持表锁
    • 不支持外键

对数据查询比较多,更新比较少的情况下

  • MEMORY
    • 不支持事务
    • 支持表锁
    • 不支持外键

索引

索引:是帮助mysql快速获取数据的一种数据结构,是本质就是一种数据结构

  • 按功能划分

    • 普通索引 :最基本的索引,没有任何限制
    • 唯一索引:索引列的值必须唯一,但允许有空值
    • 主键索引:一种特殊的唯一索引,不允许有空值
    • 组合索引:将单列索引进行组合
    • 外键索引:只有InnoDB引擎支持外键索引,用来保证数据的一致性,完整性和级联操作
    • 全文索引:快速匹配全部文档的方式。InnoDB引擎5.6版本才支持全文索引
  • 按索引的结构划分

    • B+Tree索引:InnoDB和MyISAM存储引擎默认的索引类型
    • Hash索引:MySQL和Memory存储引擎默认支持的索引类型

优化步骤

  1. 通过show processList 定位低效SQL

  2. 通过explain关键字加低效sql语句 分析执行计划

  3. 避免索引失效情况

    • 复合索引,违背最左前缀法则,索引失效,符合最左法则,但是出现跳跃,只有最左列生效
    • 范围查询,索引失效
    • 索引列上做运算操作,索引失效
    • 字符串不加单引号,索引失效
    • where 条件后面用or关键字,索引失效
    • 以%开头的like模糊查询,索引失效 可以通过覆盖索引解决
    • is NULL , is not NULL 有时候走索引,有时候不走索引
    • in 走索引, not in 不走索引
  4. 根据查询条件建立索引

  5. 搭建集群,读写分离

锁机制

锁是计算机协调多个进程或者线程访问统一资源的机制(就是避免争抢)

  • 按操作分类
    • 共享锁:(读锁)针对同一份数据,多个事务读取操作可以同时加锁,而互不影响

      Innodb: SELECT 语句 LOCK IN SHARE MODE; MyISAM: 加锁LOCK TABLE 表名 READ; 解锁:UNLOCK TABLES;

    • 排他锁:(写锁)当前的操作没有完成前,会阻断其他操作的读取和写入

      InnoDB : SELECT语句 FOR UPDATE; MyISAM: 加锁 LOCK TABLE 表名 WRITE; 解锁:UNLOCK TABLES;

  • 按粒度分类
    • 表级锁:操作时,会锁定整个表 ,不会出现死锁,锁粒度大
    • 行级锁:操作时,会锁定整行,可能会出现死锁,锁粒度小
  • 按使用方式分类
    • 悲观锁:每次查询数据都认为别人会修改,很悲观,所以查询时加锁 上面都为悲观锁
    • 乐观锁:每次查询数据时都认为别人不会修改数据,很乐观,在更新时判断再次期间有没有人区更新这个数据

    需要设置一个版本号 version 每次更新表的时候版本+1 在要更新的时候 判断操作前的版本号和当前版本号是否一致

事务

  • 事务的四大特征(ACID)
    • 原子性:每一项都是不可分割的没小单位,要么同时成功,要么同时失败。
    • 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
    • 隔离性:多个事务之间,相互独立。
    • 一致性:事务操作前后,数据总量不变

事务的隔离级别

> 如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别可以解决这些问题。
	 
  • 会存在的问题:

    • 脏读:一个事务,读取到另一个事务中没有提交的数据
    • 虚读:在同一个事务中,读取到的数据不一致
    • 幻读:一个事务操作表中的记录,另一个事务添加了一条数据,第一个事务查询不到自己的修改
  • 隔离级别:

    • read umcommited:读未提交 会产生的问题:脏读、虚读、幻读
    • read commited: 读以提交 会产生的问题:虚读、幻读
    • repeatable read : 可重复读 会产生的问题: 幻读
    • serializable: 串行化 可以解决所有的问题

    隔离级别从小到大安全性越来越高,但是效率越来越低

数据库三大范式

在一般系统中都是要遵循数据库三大范式的设计,如果按照这个设计,可能会造成数据冗余,而数据冗余可能会分化出两种问题,一个是由于数据冗余带来大量的存储磁盘消耗,另一个就是基于数据冗余的数据库表将导致应用层发开无比的复杂。

  • 部分概念

    • 函数依赖: A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
    • 完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值
    • 部分函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可
    • 传递函数依赖: A-->B, B -- >C 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A
    • 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
      • 主属性:码属性组中的所有属性
      • 非主属性:除过码属性组的属性
  • 第一范式:每一列都是不可分割的原子数据项

  • 第二范式:在1NF的基础上,非码属性必须完全依赖与码(在1NF基础上消除属性对主码的部分依赖函数)

  • 第三范式:在2NF的基础上任何非主属性不依赖其他非主属性(在2NF基础上消除传递依赖)