更多详情内容请访问:MySQL 系列文章导读

1、索引相关面试题

1. 何为索引?为何使用索引?

何为索引?为何使用索引?

索引是一种帮助 MySQL 高效获取数据的数据结构

使用它的好处如下:

  • 大大加快数据的检索速度
  • 将随机 I/O 变为顺序 I/O
  • 通过创建唯一索引还可以保证数据库表中每一行数据的唯一性
  • 加快表与表之间的连接,并可以减少查询中分组或者排序的时间,降低 CPU 消耗

2. 简述索引数据结构的演化?

简述索引数据结构的演化?

二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质:

  1. 任意节点左子树不为空,则左子树的值均小于根节点的值;
  2. 任意节点右子树不为空,则右子树的值均大于于根节点的值;
  3. 任意节点的左右子树也分别是二叉查找树;
  4. 没有键值相等的节点;

对于某些情况(例如插入的节点是有序的),二叉查找树会退化成一个线性链表的形式,因此为了性能着想,需要这个二叉树的平衡的,从而引出新的结构——平衡二叉树(AVL)

AVL 树是带有平衡条件的二叉查找树,任意节点的子树高度差都小于等于 1,并且任何一个节点的左子树或者右子树都是平衡二叉树

由于维护高度平衡付出的代价比从中获得效益收益还要大,故而实际的应用并不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树

通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍。它是一种弱平衡二叉树(由于是弱平衡,可以推出,相同的节点情况下,AVL 树的高度低于红黑树),相对于要求严格的 AVL 树来说,它的旋转次数变少,所以对于搜索、插入、删除操作多的情况下,我们就用红黑树

使用红黑树,树的高度会特别高,I/O次数依旧很大

B 树是为了磁盘或其它存储设备而设计的一种平衡多路查找树,与红黑树相比,在相同的的节点的情况下,一颗 B 树的高度远远小于红黑树的高度

B+ 树是应文件系统所需而产生的一种 B 树的变形树(文件的目录一级一级索引,只有最底层的叶子节点(文件)保存数据)非叶子节点只保存索引,不保存实际的数据,数据都保存在叶子节点中

3. 为何使用 B+ 树而非 B树?⭐

为何使用 B+ 树而非 B树?

  1. B+ 树更适合外部存储,由于内节点不存放真正数据,一个节点节点可以存储更多的关键字,每个节点能索引的范围更大更精确,也意味着 B+ 树单次磁盘 IO 的信息量大于 B 树,I/O 次数相对减少
  2. MySQL 是一种关系型数据库,区间访问是常见的一种情况,B+ 树叶结点增加的链指针,加强了区间访问性,可使用在区间查询的场景;而使用 B 树则无法进行区间查找
  3. B+ 树的查询效率更加稳定,任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当

4. Hash 索引和 B+ 树索引的区别?

Hash 索引和 B+ 树索引的区别?

范围查询 最左原则 排序 模糊查询 等值查询
Hash 索引 不支持 不支持 不支持 不支持 一般而言效率比 B+ 树快
B+ 树索引 支持 支持 支持 支持 一般而言效率比 Hash 慢
  1. Hash 索引不能进行范围查询,而 B+ 树可以。

    这是因为 Hash 索引指向的数据是无序的,而 B+ 树的叶子节点是个有序的链表。

  2. Hash 索引不支持联合索引的最左侧原则(即联合索引的部分索引无法使用),而 B+ 树可以。

    对于联合索引来说,Hash 索引在计算 Hash 值的时候是将索引键合并后再一起计算 Hash 值,所以不会针对每个索引单独计算 Hash 值。因此如果用到联合索引的一个或多个索引时,联合索引无法被利用。

  3. Hash 索引不支持 Order BY 排序,而 B+ 树支持。

    因为 Hash 索引指向的数据是无序的,因此无法起到排序优化的作用,而 B+ 树索引数据是有序的,可以起到对该字段 Order By 排序优化的作用。

  4. Hash 索引无法进行模糊查询。而 B+ 树使用 LIKE 进行模糊查询的时候,LIKE 后面前模糊查询(比如 % 开头)的话可以起到优化的作用。

  5. Hash 索引在等值查询上比 B+ 树效率更高。

    不过也存在一种情况,就是索引列的重复值如果很多,效率就会降低。这是因为遇到 Hash 冲突时,需要遍历桶中的行指针来进行比较,找到查询的关键字非常耗时。所以 Hash 索引通常不会用到重复值多的列上,比如列为性别,年龄等。

5.MyISAM 与 InnoDB 中实现 B+ 树索引方式的区别?

MyISAM 与 InnoDB 中实现 B+ 树索引方式的区别?

  • MyISAM:B+ 树叶节点中存放的是数据记录的地址,只有“非聚簇索引”这一概念
  • InnoDB:既有聚簇索引,也有非聚簇索引(存放相应记录的主键和索引字段,而非地址)

6. 为何聚簇索引、非聚簇索引,二者有何区别?⭐

为何聚簇索引、非聚簇索引,二者有何区别

  • 聚簇索引:
    1. 使用记录主键值的大小作为索引,按照其大小顺序组织到一颗 B+ 树中
    2. 叶子节点中存放的就是整张表的行记录数据
    3. 通过主键聚集数据,如果没有定义主键,InnoDB 会选择非空的唯一索引替代;如果也没有这样的索引,会隐式的定义一个主键来作为索引
    4. 一张表最多只能有一个聚簇索引
    5. 聚簇索引的顺序就是数据的物理存储顺序,在创建任何非聚簇索引之前创建聚簇索引
  • 非聚簇索引(辅助索引、二级索引):
    1. 叶子节点只存放主键值和索引字段的值;其他节点存储索引值
    2. 一张表可以存在多个非聚簇索引
    3. 索引顺序与数据物理排列顺序无关,只是逻辑上的连续

7.为何覆盖索引?什么是回表查询?非聚簇索引一定会回表查询吗?⭐

为何覆盖索引?什么是回表查询?非聚簇索引一定会回表查询吗?

如果一个索引包含所有需要查询的字段的值,就称为“覆盖索引”。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作

在 InnoDB 存储引擎中,如果不是主键索引,叶子节点存储的是主键值和相应字段的索引值,找到这个主键值,再通过主键去聚簇索引中再去查找一遍,该过程就称为“回表

假设,有一员工表(在年龄上建立了索引),那么当进行 select id,age from emp where age = 20; 这样一条语句的时候,因为在非聚簇索引的叶子节点上已经有 id 和 age 的值,所以就不需要再回表查询,

因此非聚簇索引并不一定会回表查询

8. 何为最左前缀原则?联合索引又是什么?⭐

何为最左前缀原则?联合索引又是什么?

MySQL 可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引

最左前缀原则最左优先,以最左边的为起点任何连续的索引都能匹配上,直到遇到范围查询停止匹配

比如 a = 1 and b = 2 and c > 3 and d = 4 ,如果建立 (a,b,c,d) 顺序的联合索引,d 是用不到索引的,如建立 (a,b,d,c) 的索引则都可以用到,a,b,d 的顺序可以任意调整。

9. 为何推荐使用自增主键作为索引?如果不设定主键会发生什么?⭐

为何推荐使用自增主键作为索引?如果不设定主键会发生什么?

防止页分裂。聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。

如果主键不是自增id,它会不断地调整数据的物理地址、分页;但如果是自增的 id,它只需要一页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高

如果不主动设置主键,InnoDB 存储引擎就会选择第一个唯一索引列作为主键列,并把它用作一个聚簇索引;如果没有这样的列,就会使用隐藏的自增字段作为主键,生成聚簇索引。

10. 创建了索引一定会使用到吗?索引失效的几种情况?⭐

创建了索引一定会使用到吗?索引失效的几种情况?

创建了索引但并不是一定就会使用到,以下是几种常见的索引失效的案例:

  1. like 查询以通配符“%”开头
  2. 类型转换(隐式转换),列计算、函数
  3. 不等于运算符(!=<>)索引失效
  4. is null 可以使用,is not null 索引失效
  5. or 语句前后没有同时使用索引
  6. 不符合最左匹配原则
  7. MySQL 认为走全表扫描比索引更加快也会导致索引失效

11. 索引的设计原则?哪些情况适合创建索引?哪些情况不适合?⭐

索引的设计原则?哪些情况适合创建索引?哪些情况不适合?

  • 适合创建索引:
    1. 字段的数值有唯一性的限制
    2. 频繁作为 where 查询条件的字段
    3. 经常需要 group by 或者 order by 的列
    4. DISTINCT 字段
    5. 多表连接有关联的字段
    6. 区分度高的列作为索引
    7. 联合索引中使用最频繁的列放到最左侧
    8. 多个字段都要创建索引的情况下,联合索引由于单列索引
  • 不适合创建索引:
    1. 频繁增删改的字段
    2. where 条件里用不到的字段
    3. 表记录太少,无需建立索引
    4. 数据重复且分布平均的字段,例如:性别

12. 常见的一些优化方式?日常工作中是如何优化 SQL 的?⭐

常见的一些优化方式?日常工作中是如何优化 SQL 的?

  1. 表结构优化
    • 只包含数值信息的字段不要设计为字符型
    • 尽可能使用 varchar 替代 char
    • 恰当的创建索引
    • 分库分表,读写分离
  2. 查询优化
    • 避免索引失效的一些情况
    • 尽量少使用子查询,能使用外连接就使用外连接
    • 对于 EXISTS 和 IN 的选择,遵循“小表驱动大表”的原则
    • 优化 SQL 语句的写法,例如分页优化(select * from tmp limit 2000000000,10;
  3. 索引优化
    • 尽可能的使用复合索引而不是索引的组合;
    • 创建索引尽量让辅助索引进行索引覆盖而不是回表;
    • 能使用短索引就是用短索引,这样可以在非叶子节点存储更多的索引列降低树的层高,并且减少空间的开销;
    • 尽量扩展索引,而不是去新建索引
  4. 慢查询优化
    • 分析慢查询日志
    • 分析 SQL 执行语句是否命中索引

13. 几种常见的索引类型?

几种常见的索引类型?

  • 功能逻辑:普通索引、唯一索引、主键索引、全文索引
  • 物理实现方式:聚簇索引、非聚簇索引
  • 作用字段个数:单列索引、联合索引

2、事务相关面试题

1. 什么是 ACID?⭐

什么是 ACID?

  1. 原子性(Atomicity):要么全部提交,要么全部失败回滚
  2. 一致性(Consistency):数据从一个合法性状态变换到另外一个合法性状态
  3. 隔离性(Isolation):多个数据并发时,事务与事务之间相对隔离,互不打扰
  4. 持久性(Durability):事务一旦提交,对数据库的改变就是永久性的不受故障等因素的影响

2. 并发事务会带来哪些问题?不可重复读与幻读的区别?⭐

并发事务会带来哪些问题?不可重复读与幻读的区别?

  • 脏写:事务 A 修改了 另一未提交事务 B 修改过的数据,事务 B 回滚,此时就发生了脏写
  • 脏读:事务 A 读取了事务 B 更新了但未提交的字段,事务 B 回滚,此时就发生了脏读
  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果不一致,这就是不可重复读
  • 幻读:事务 A 在一个表中读取了数据,事务 B 在该表中插入了一些新的数据,事务 A 再次读取同一张表,发现多了几行数据,这就是幻读

不可重复读侧重于修改,幻读侧重于新增或删除(多了或少量行),脏读是一个事务回滚影响另外一个事务。

3. 如何解决并发问题?MySQL 的事务隔离级别?⭐

如何解决并发问题?MySQL 的事务隔离级别?

隔离级别 脏写 脏读 不可重复读 幻读
READ UNCONMITED(读未提交)
READ COMMITED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行)

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重复读),并且 MySQL 在该隔离级别下通过 MVCC 机制解决了幻读的问题

4. MySQL 中的事务回滚机制?

MySQL 中的事务回滚机制?

恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。当事务已经被提交之后,就无法再次回滚了。

5. 什么是 WAL?为什么需要?

什么是 WAL?为什么需要?

WAL 主要是指 MySQL 在执行写操作的时候并不是立刻更新到磁盘上,而是先记录在日志中,之后在合适的时间更新到磁盘中。日志主要分为 undo log、redo log、bin log、relay log。

如果不采用预写日志机制,而直接采用磁盘更新数据,首先会增加 I/O 资源消耗;其次磁盘存数据采用的是随机存储的方式,这就使得在存放数据的时候不仅需要记录下存放的数据值,还需要记录存放数据的地址,存储速度相对比较慢。而日志存储是连续存储,因此在存数据的时候只需要记录下首地址即可,其余数据记录偏移量,可以进一步提高性能。

总结而言,好处是保证了数据操作的原子性和持久性,具体如下:

  1. 读和写可以完全地并发执行」,不会互相阻塞
  2. 先写入 log 中,磁盘写入从「随机写变为顺序写」,降低了 client 端的延迟。并且,由于顺序写入大概率是在一个磁盘块内,这样产生的 I/O 次数也大大降低
  3. 写入日志当数据库崩溃的时候「可以使用日志来恢复磁盘数据

3、锁相关面试题

1. MySQL 锁的分类(划分)?⭐

MySQL 锁的分类(划分)?

  • 对数据的操作类型:
    • 读锁/共享锁/s 锁
      1. 描述:其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排它锁),直到已释放所有共享锁
      2. 用法:select ... lock in share mode;
    • 写锁/排它锁/x 锁
      1. 描述:事务 T 对数据 A 加上排他锁后,则其他事务不能再对 A 加任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据
      2. 用法:select ... for update;
  • 锁粒度角度:
    • 行级锁:开销大,加锁慢,会出现死锁。发生锁冲突概率最低,并发度最高
      1. 记录锁(Record Lock):单条索引上加锁,record lock 永远锁的是索引,而非数据本身
      2. 间隙锁(Gap Lock):锁定一个范围,不包括记录本身
      3. 临键锁(Next-key Lock):锁定一个范围,包含记录本身
    • 表级锁:开销小,加锁快,不会出现死锁。发生锁冲突概率最高,并发度最低
      1. 意向锁
      2. 表级别的 S 锁、X 锁
    • 页级锁:开销和加锁时间介于表锁和行锁之间,会出现死锁,并发度一般
  • 对锁的态度划分:
    • 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性
    • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
  • 加锁的方式:
    • 隐式锁
    • 显式锁
  • 其他:
    • 死锁:多个进程在执行时候,因为争夺资源造成相互等待的现象,进程一直处于等待中,无法得到释放,这种状态就叫做死锁
    • 全局锁:对整个数据库加锁,可以使得整个库处于只读状态,比如做全库备份时

2. 乐观锁与悲观锁的原理与应用场景?⭐

乐观锁与悲观锁的原理与应用场景?

  • 乐观锁(Optimistic Lock):假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁不能解决脏读的问题。

    每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量

  • 悲观锁(Pessimistic Lock):假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

    悲观锁,顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会 block 直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。适用于多写的应用场景

3. 如何处理死锁?如何避免死锁?⭐

如何处理死锁?如何避免死锁?

当发生死锁时可以通过以下两个方法处理死锁

  1. 通过 innodblockwait_timeout设置超时时间,一直等待直到超时
  2. 发起死锁检测,发现死锁之后,主动回滚死锁中的事务,不需要其他事务继续

可以通过以下几个途径尽量去避免死锁的产生:

  1. 精心设计索引使锁更精确(InnoDB 行锁的实现),从而减少锁冲突的机会
  2. 可以在事务开始的时候通过 for update 语句来提前获取必要的锁,哪怕这些行的更改语句是之后才执行
  3. 在事务中,如果要更新记录,应该直接申请足够级别的锁,即排它锁,而非共享锁
  4. 如果事务需要修改或锁定多个表,则应在每个事务中以相同的顺序使用加锁语句
  5. 除非必须,查询时不要显式加锁。因为 MySQL 中的 MVCC 可以实现事务中的查询不用加锁,优化事务性能
  6. 更改事务隔离级别

4. InnoDB 引擎中的行锁是如何实现的?⭐

InnoDB 引擎中的行锁是如何实现的?

基于索引来完成行锁

例:select * from tab_with_index where id = 1 for update;

for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么 InnoDB 将完成表锁,并发将无从谈起

5. 什么是 MVCC?什么是当前读?什么是快照读?⭐

什么是 MVCC?什么是当前读?什么是快照读?

  • MVCC:多版本并发控制。通过数据行的多个版本管理实现数据库的并发控制(读写不冲突),同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题
  • 快照读:读取的记录可见版本(可能是历史记录),不用加锁
  • 当前读:读取记录的最新版本,并且当前读返回的记录都会加上锁,保证其他事务不会并发修改该记录。对数据进行增删改都会进行当前读

6. 简要概述下 MVCC 的实现原理?⭐

简要概述下 MVCC 的实现原理?

  1. 隐含字段

    • db_trx_id:记录操作该数据事务的 id,每处理一个事务其值 +1
    • db_roll_ptr:回滚指针,指向该条数据的上一版本在 undo log 里的位置指针
    • db_row_id:隐藏 id,当创建的表没有设置主键且不存在合适的索引作为聚簇索引时创建的
  2. Undo Log 日志

    • insert undo log事务插入时产生,事务回滚时需要,事务提交时丢弃
    • update undo log进行 update、delete 时产生的 undo log,不仅在回滚事务时需要,快照读时也需要。不能随便删除;只有在快速读或事务回滚不涉及该日志时,对应的日志才会被 purge 线程统一清除
  3. Read View 读视图

    • 事务进行快照读操作的时候产生的读视图,在该事务执行快照读的那一刻,会生成一个数据系统当前的快照,记录并维护系统当前活跃事务(未提交事务)的 ID

    • 在 READ COMMITED(读已提交)隔离级别下,每个快照读都会生成并获取最新的 Read View

      在 REPEATABLE READ(可重复读)隔离级别下,同一事务中第一个快照读才会创建 Read View,之后的快照读获取的都是同一个 Read View

    • creator_trx_id:表示生成该 Read View 的快照读操作产生的事务 id。只有在对表中的记录做改动时才会为事务分配事务 id,否则在一个只读事务中的事务 id 值都默认为 0。

    • m_ids:表示在生成 Read View 时当前系统中活跃的读写事务的 事务id列表

    • min_trx_id:活跃的事务中最小的事务 ID。

    • max_trx_id:表示生成 Read View 时系统中应该分配给下一个事务的 id 值。

  4. MVCC 整体操作流程

    • 首先获取事务自己的版本号,也就是事务 ID;
    • 获取 Read View;
    • 查询得到的数据,然后与 Read View 中的事务版本号进行比较;
    • 如果不符合 Read View 规则,就需要从 Undo Log 中获取历史快照;
    • 最后返回符合规则的数据。

7. MySQL 如何在 REPEATABLE-READ 事务隔离级别解决了幻读这一问题?⭐

MySQL 如何在 REPEATABLE-READ 事务隔离级别解决了幻读这一问题?

通过 MVCC 机制。在查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交更新后的结果。

4、存储引擎相关面试题

1. InnoDB 与 MyISAM 有什么区别?⭐

InnoDB 与 MyISAM 有什么区别?

InnoDB MyISAM
支持外键的事务型存储引擎 不支持外键的非事务型存储引擎
InnoDB 主键生成聚簇索引(如果没有主键,会使用唯一索引列作为主键;如果没有这样的列,会创建一个隐藏字段 id) MyISAM 只拥有聚集索引(二级索引、辅助索引)
支持表、行(默认)级锁 支持表级锁
支持 MVCC,不支持全文索引(5.7 版本前) 不支持 MVCC,支持全文索引
不保存表的具体行数,执行 count(*) 时需要全表扫描 用一个变量保存了整个表的行数,执行 count(*) 时只需要读出该变量即可,速度很快
InnoDB 的 B+ 树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值和该索引值 MyISAM 的 B+ 树主键索引和辅助索引的叶子节点都是数据文件的地址指针
空间、内存使用率高,插入速度低 空间、内存使用率低,插入速度快
数据和索引一起保存 .ibd(8.0 版本后) 表结构 .frm;索引 .myi;数据 .myd
适合插入更新频繁的 适合读多更新少的

2. SQL 的执行顺序与书写顺序?⭐

SQL 的执行顺序与书写顺序?

  • 书写顺序:

    select → distinct → from → join → on → where → group by → having → union → order by → limit

  • 执行顺序:

    from → on → join → where → group by → having → select → distinct → union → order by → limit

3. 如何执行一条 SQL 的?具体步骤大致有哪些?

如何执行一条 SQL 的?具体步骤大致有哪些?

  1. 客户端请求
  2. 连接器(验证用户身份,给予权限)
  3. 查询缓存(存在缓存则直接返回,不存在则执行后续操作)
  4. 分析器(对SQL进行词法分析和语法分析操作)
  5. 优化器(主要对执行的sql优化选择最优的执行方案方法)
  6. 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)
  7. 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)

5、其他相关面试题

1. 三范式?⭐

三范式?

  • 第一范式:每个列都不可以再拆分。
  • 第二范式:非主键列完全依赖于主键,而不能是依赖于主键的一部分。
  • 第三范式:非主键列只依赖于主键,不依赖于其他非主键。

设计数据库结构的时候会尽量遵守三范式,但事实上出于对性能的考虑,并不会完全遵守三范式

2. 视图是干什么的?可以更改吗?

视图是干什么的?可以更改吗?

视图是虚拟的表,可以将视图理解为存储起来的 SELECT 语句

  • 可以简化复杂的 SQL 操作
  • 隐藏具体的细节,保护敏感数据

视图创建以后可以使用与表相同的方式利用他们。视图不能被索引

对于某些视图比如未使用联结、子查询、分组、函数、Distinct、Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新

3. char 与 varchar 的区别?

char 与 varchar 的区别?

实际功能角度来考虑:

  • char 是一个定长字段,假如申请了 char(10) 的空间,那么无论实际存储多少内容。该字段都占用 10
  • varchar 是变长的,也就是说申请的只是最大长度,占用的空间为实际字符长度 +1,最后一个字符存储使用了多长的空间

存储引擎的角度来考虑:

  • MyISAM 最好使用 char,这样可以使得整个表静态化,从而使数据检索更快,用空间换时间
  • InnoDB 建议使用 varchar,因为其内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素是数据行使用的存储总量

4. varchar(10) 和 int(10) 中各自 10 的含义

varchar(10) 和 int(10) 中各自 10 的含义

  • varchar 的 10 代表了申请的空间长度,也是可以存储的数据的最大长度
  • int 的 10 只是代表了展示的长度,不足 10 位以 0 填充

也就是说:varchar(10) 和 int(10) 所能存储的数字大小以及占用的空间都是相同的,只是在展示时按照长度展示.

5. 常见的几种约束?

常见的几种约束?

  • 主键约束:primary key;
  • 外键约束:foreign key;
  • 唯一约束:unique;
  • 检查约束:check;(8.0 版本以下不支持)
  • 非空约束:not null;
  • 默认值约束:default;

count(1)、count(*) 与 count(列名) 的执行区别?⭐

count(1)、count(*) 与 count(列名) 的执行区别?

  • count(*):包括了所有的列,相当于行数,在统计结果的时候, 不会忽略列值为NULL
  • count(1):包括了忽略所有列,用1代表代码行,在统计结果的时候, 不会忽略列值为NULL
  • count(列名):只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者 0,而是表示 null)的计数, 即某个字段值为 NULL 时,不统计。

对于 MyISAM 存储引擎来讲,其中有一个字段记录了表中记录量,因此使用 count(*) 或者 count(1) 时效率更快

空值与 null 的区别?

空值与 null 的区别?

空值 null 值
占用空间 长度为 0,是不占用空间的 长度为 null,占用空间的
插入/查询方式 可以使用 =、!=、<、>等运算符 使用 is null / is not null
count(字段) 不会过滤空值 会空滤 null 值
索引字段 常见索引不失效,空间索引列必须为 not null

触发器、函数、存储过程、游标?

触发器、函数、存储过程、游标?

  • 触发器:使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的
  • 函数:是 MySQL 数据库提供的内部函数(也可以自定义函数)。这些内部函数可以帮助用户更加方便的处理表中的数据
  • 存储过程:存储过程是存储在数据库目录中的一坨的声明性 SQL 语句,数据库中的一个重要对象,有效提高了程序的性能
  • 游标:相当于指针的作用,一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要


END

本文作者:
文章标题:MySQL 常见面试题
本文地址:https://www.pendulumye.com/mysql/375.html
版权说明:若无注明,本文皆个人学习记录原创,转载请保留文章出处。
最后修改:2022 年 09 月 25 日
千山万水总是情,给个一毛行不行💋