- [面试题]Java【基础】
- [面试题]Java【虚拟机】
- [面试题]Java【并发】
- [面试题]Java【集合】
- [面试题]MySQL
- [面试题]Maven
- [面试题]Spring Boot
- [面试题]Spring Cloud
- [面试题]Spring MVC
- [面试题]Spring
- [面试题]MyBatis
- [面试题]Nginx
- [面试题]缓存
- [面试题]Redis
- [面试题]消息队列
- [面试题]Kafka
- [面试题]RabbitMQ
- [面试题]MongoDB
- [面试题]Dubbo
- [面试题]Git
- [面试题]Jenkins
- [面试题]Linux
- [面试题]Netty
- [面试题]Zookeeper
- [面试题]计算机网络
- [面试题]分库分表
以下面试题,基于网络整理,和自己编辑。具体参考的文章,会在文末给出所有的链接。
MySQL 涉及的内容非常非常非常多,所以面试题也容易写的杂乱。当年,我们记着几个一定要掌握的重心:
重点的题目,添加了【重点】前缀。
-
索引。
-
锁。
-
事务和隔离级别。
因为 MySQL 还会有部分内容和运维相关度比较高,所以本文我们分成两部分【开发】【运维】两部分。
-
对于【开发】部分,我们需要掌握。
-
对于【运维】部分,更多考验开发的知识储备情况,当然能回答出来是比较好的,特别是对于高级开发工程师、架构师等。
开发
为什么互联网公司一般选择 MySQL 而不是 Oracle?
免费、流行、够用。
当然,这个回答要稍微润色下。不过一般,很少问这个问题了。
数据库的三范式是什么?什么是反模式?
重点在于反模式的回答。实际开发中,不会严格遵守三范式。
胖友直接看 《服务端指南 数据存储篇 | MySQL(07) 范式与反模式》 。
MySQL 有哪些数据类型?
MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。具体可以看看 《MySQL 数据类型》 文档。
正确的使用数据类型,对数据库的优化是非常重要的。
MySQL 中 varchar 与 char 的区别?varchar(50) 中的 50 代表的涵义?
1、varchar 与 char 的区别,char 是一种固定长度的类型,varchar 则是一种可变长度的类型。
2、varchar(50) 中 50 的涵义最多存放 50 个字符。varchar(50) 和 (200) 存储 hello 所占空间一样,但后者在排序时会消耗更多内存,因为 ORDER BY col 采用 fixed_length 计算 col 长度(memory引擎也一样)。
所以,实际场景下,选择合适的 varchar 长度还是有必要的。
int(11) 中的 11 代表什么涵义?
int(11) 中的 11 ,不影响字段存储的范围,只影响展示效果。具体可以看看 《MySQL 中 int 长度的意义》 文章。
金额(金钱)相关的数据,选择什么数据类型?
方式一,使用 int 或者 bigint 类型。如果需要存储到分的维度,需要 *100 进行放大。
方式二,使用 decimal 类型,避免精度丢失。如果使用 Java 语言时,需要使用 BigDecimal 进行对应。
一张表,里面有 ID 自增主键,当 insert 了 17 条记录之后,删除了第 15,16,17 条记录,再把 MySQL 重启,再 insert 一条记录,这条记录的 ID 是 18 还是 15?
一般情况下,我们创建的表的类型是 InnoDB ,如果新增一条记录(不重启 MySQL 的情况下),这条记录的 ID 是18 ;但是如果重启 MySQL 的话,这条记录的 ID 是 15 。因为 InnoDB 表只把自增主键的最大 ID 记录到内存中,所以重启数据库或者对表 OPTIMIZE 操作,都会使最大 ID 丢失。
但是,如果我们使用表的类型是 MyISAM ,那么这条记录的 ID 就是 18 。因为 MyISAM 表会把自增主键的最大 ID 记录到数据文件里面,重启 MYSQL 后,自增主键的最大 ID 也不会丢失。
最后,还可以跟面试官装个 x ,生产数据,不建议进行物理删除记录。
表中有大字段 X(例如:text 类型),且字段 X 不会经常更新,以读为为主,请问您是选择拆成子表,还是继续放一起?写出您这样选择的理由
拆带来的问题:连接消耗 + 存储拆分空间。
如果能容忍拆分带来的空间问题,拆的话最好和经常要查询的表的主键在物理结构上放置在一起(分区) 顺序 IO ,减少连接消耗,最后这是一个文本列再加上一个全文索引来尽量抵消连接消耗。
不拆可能带来的问题:查询性能。
如果能容忍不拆分带来的查询性能损失的话,上面的方案在某个极致条件下肯定会出现问题,那么不拆就是最好的选择。
实际场景下,例如说商品表数据量比较大的情况下,会将商品描述单独存储到一个表中。即,使用拆的方案。
MySQL 有哪些存储引擎?
MySQL 提供了多种的存储引擎:
InnoDB
MyISAM
MRG_MYISAM
MEMORY
CSV
ARCHIVE
BLACKHOLE
PERFORMANCE_SCHEMA
FEDERATED
…
具体每种存储引擎的介绍,可以看看 《数据库存储引擎》 。
如何选择合适的存储引擎?
提供几个选择标准,然后按照标准,选择对应的存储引擎即可,也可以根据 常用引擎对比 来选择你使用的存储引擎。使用哪种引擎需要根据需求灵活选择,一个数据库中多个表可以使用不同的引擎以满足各种性能和实际需求。使用合适的存储引擎,将会提高整个数据库的性能。
- 是否需要支持事务。
- 对索引和缓存的支持。
- 是否需要使用热备。
- 崩溃恢复,能否接受崩溃。
- 存储的限制。
- 是否需要外键支持。
目前开发已经不考虑外键,主要原因是性能。具体可以看看 《从 MySQL 物理外键开始的思考》 文章。
目前,MySQL 默认的存储引擎是 InnoDB ,并且也是最主流的选择。主要原因如下:
【最重要】支持事务。
支持行级锁和表级锁,能支持更多的并发量。
查询不加锁,完全不影响查询。
支持崩溃后恢复。
在 MySQL5.1 以及之前的版本,默认的存储引擎是 MyISAM ,但是目前已经不再更新,且它有几个比较关键的缺点:
不支持事务。
使用表级锁,如果数据量大,一个插入操作锁定表后,其他请求都将阻塞。
也就是说,我们不需要花太多力气在 MyISAM 的学习上。
请说明 InnoDB 和 MyISAM 的区别
InnoDB | MyISAM | |
---|---|---|
事务 | 支持 | 不支持 |
存储限制 | 64TB | 无 |
锁粒度 | 行锁 | 表锁 |
崩溃后的恢复 | 支持 | 不支持 |
外键 | 支持 | 不支持 |
全文检索 | 5.7 版本后支持 | 支持 |
更完整的对比,可以看看 《数据库存储引擎》 的 「常用引擎对比」 小节。
请说说 InnoDB 的 4 大特性?
貌似我面试没被问过…反正,我是没弄懂过~~
插入缓冲(insert buffer)
二次写(double write)
自适应哈希索引(ahi)
预读(read ahead)
为什么 SELECT COUNT(*) FROM table 在 InnoDB 比 MyISAM 慢?
对于 SELECT COUNT(*) FROM table 语句,在没有 WHERE 条件的情况下,InnoDB 比 MyISAM 可能会慢很多,尤其在大表的情况下。因为,InnoDB 是去实时统计结果,会全表扫描;而 MyISAM 内部维持了一个计数器,预存了结果,所以直接返回即可。
详细的原因,胖友可以看看 《高性能 MySQL 之 Count 统计查询》 博客。
各种不同 MySQL 版本的 Innodb 的改进?
这是一个选择了解的问题。
MySQL5.6 下 Innodb 引擎的主要改进:
online DDL
memcached NoSQL 接口
transportable tablespace( alter table discard/import tablespace)
MySQL 正常关闭时,可以 dump 出 buffer pool 的( space, page_no),重启时 reload,加快预热速度
索引和表的统计信息持久化到 mysql.innodb_table_stats 和 mysql.innodb_index_stats,可提供稳定的执行计划
Compressed row format 支持压缩表
MySQL5.7 下 Innodb 引擎的主要改进:
1、修改 varchar 字段长度有时可以使用
这里的“有时”,指的是也有些限制。可见 《MySQL 5.7 online ddl 的一些改进》 。
2、Buffer pool 支持在线改变大小
3、Buffer pool 支持导出部分比例
4、支