2020字节跳动数据库⾯试题及答案(1)第⼆部分NoSQL部分已发布:
题⽬列表
数据库三范式
分别说⼀下范式和反范式的优缺点
Mysql 数据库索引。B+ 树和 B 树的区别
为什么 B+ 树⽐ B 树更适合应⽤于数据库索引,除了数据库索引,还有什么地⽅⽤到了(操作系统的⽂件索引)聚簇索引和⾮聚簇索引
前缀索引和覆盖索引
介绍⼀下数据库的事务
Mysql 有哪些隔离级别
Mysql 什么情况会造成脏读、不可重复度、幻读?如何解决sql查询面试题及答案
Mysql 在可重复读的隔离级别下会不会有幻读的情况,为什么?
Mysql 事务是如何实现的
Binlog 和 Redo log 的区别是什么,分别是什么⽤?
谈⼀谈 MVCC 多版本并发控制
Innodb 和 MyISAM 的区别是什么
Innodb 的默认加锁⽅式是什么,是怎么实现的
如何⾼效处理⼤库 DDL
Mysql 索引重建
对于多列索引,哪些情况下能⽤到索引,哪些情况⽤不到索引
为什么使⽤数据库索引可以提⾼效率,在什么情况下会⽤不到数据库索引?
共享锁和排他锁的使⽤场景
关系型数据库和⾮关系数据库的优缺点
Mysql 什么情况会造成慢查,如何查看慢查询
如何处理慢查询,你⼀般是怎么处理慢查询的
Mysql 中 varchar 和 char 的区别
数据库外键的优缺点
有没有使⽤过数据库的视图
Mysql 中插⼊数据使⽤⾃增 id 好还是使⽤ uuid,为什么?
Mysql 有哪些数据类型,使⽤的时候有没有什么注意点
Mysql 集有哪⼏种⽅式,分别适⽤于什么场景
Mysql 主从模式如何保证主从强⼀致性
Mysql 集如何保证主从可⽤性
Mysql 读写分离有哪些解决办法
数据库三范式
1. 第⼀范式:确保每列的原⼦性,每列都是不可分割的最⼩数据单元
2. 第⼆范式:在第⼀范式的基础上,要求每列都和主键相关
3. 第三范式:在第⼆范式的基础上,要求其他列和主键是直接相关,⽽不是间接相关
分别说⼀下范式和反范式的优缺点
1.范式化
优点:
减少数据冗余
表中重复数据较少,更新操作⽐较快
范式化的表通常⽐反范式化的表⼩
缺点:
在查询的时候通常需要很多的关联,降低性能
增加了索引优化的难度
2.反范式化
优点:
可以减少表的关联
更好的进⾏索引优化
缺点:
数据重复冗余
对数据表的修改需要更多的成本
Mysql 数据库索引。B+ 树和 B 树的区别
MySQL数据库索引和存储引擎有关,MyISAM和InnoDB只⽀持BTREE索引。MEMORY和HEAP⽀持HASH和BTREE索引
B+树和B树的区别
B+树⾮叶⼦节点只存储关键字和指向⼦节点的指针,⽽B树还存储了数据,在同样⼤⼩的情况下,B+树可以存储更多的关键字B+树叶⼦节点存储了所有关键字和数据,并且多个节点⽤链表连接。可以快速⽀撑范围查
B+树⾮叶⼦节点不存储数据,所以查询时间复杂度固定为O(logN),B树查询时间复杂度不固定,最好是O(1)
参考⽂章:
为什么 B+ 树⽐ B 树更适合应⽤于数据库索引,除了数据库索引,还有什么地⽅⽤到了(操作系统的⽂件索引)
因为B树叶⼦节点和⾮叶⼦结点都存储了数据,这样就导致了⾮叶⼦结点能保存的关键字和指针变少,如果要保存⼤量数据,只能增加树的⾼度,导致IO操作变多,查询性能降低
除数据库索引,还有操作系统的⽂件索引⽤到了B树。参考⽂章:
聚簇索引和⾮聚簇索引
聚簇索引,⼜叫主键索引,每个表只有⼀个主键索引,叶⼦节点保存主键的值和数据
⾮聚簇索引,⼜叫辅助索引,叶⼦节点保存索引字段的值和主键的值
前缀索引和覆盖索引
1.前缀索引
对于列的值较长,⽐如BLOB、TEXT、VARCHAR,就必须建⽴前缀索引,即将值的前⼀部分作为索引。这样既可以节约空间,⼜可以提⾼查询效率。但⽆法使⽤前缀索引做ORDER BY和GROUP BY,也⽆法使⽤前缀索引做覆盖扫描。
2.覆盖索引
select的数据列从索引中就能获得,不必再从数据表中读取。如果⼀个索引包含了(或覆盖了)满⾜查询语句中字段与条件的数据就叫做覆盖索引。
当发起⼀个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息
参考⽂章:
介绍⼀下数据库的事务
事务是⼀个操作序列,这些操作要么全部执⾏,要么都不执⾏。
事务具有四⼤特性:A(原⼦性)、C(⼀致性)、I(隔离性)、D(持久性)
Mysql 有哪些隔离级别
Mysql 什么情况会造成脏读、不可重复读、幻读?如何解决
脏读:有两个事务A和B,A读取已经被B修改但未提交的字段,此时B回滚,那么A读取的字段就是临时且⽆效的。可以提⾼隔离级别,改成读已提交
不可重复读:有两个事务A和B,A读取了⼀个字段值,然后B更新并且提交事务,A再重新读取这个字段,就和之前不相等了。可以提⾼隔离级别,改成可重复读
幻读:有两个事务A和B,A读取某个范围内的记录时,B⼜在该范围内插⼊了新的记录并提交,当事务A再次读取该范围的记录时,会产⽣幻⾏。可以升级隔离级别到串⾏化,或者使⽤MVCC + next-key锁机制实现
Mysql 在可重复读的隔离级别下会不会有幻读的情况,为什么?不会。InnoDB存储引擎默认隔离级别为RR,通过MVCC + next-key锁机制解决了幻读的问题。
PS:其实严格来说,是存在幻读的。。。可以尝试⼀下这个操作,A开启事务,执⾏查询,此时B开启事务新增⼀条数据并提交,此时A再查询,发现没有幻读,但是如果A执⾏⼀个update操作,再查询,会发现出现了幻读。我认为应该是A在执⾏update操作的时候,新建了⼀条创建版本号为A事务版本号的记录,然后标记B事务创建的记录为待删除的,查询的版本号依据是删除版本号为空或⼤于当前版本号,并且创建版本号⼩于等于当前事务版本号,那么这⾥刚刚A更新的这条数据,显然也符合查询的条件,所以也会被查出来。
MVCC版本号原理参考⽂章:
详细测试参考⽂章:
Mysql 事务是如何实现的
原⼦性:通过undo log实现的。每条数据变更都伴随⼀条undo log⽇志的⽣成,当系统发⽣错误或执⾏回滚根据undo log做逆向操作持久性:通过redo log实现的。redo log记录了数据的修改⽇志。数据持久化到磁盘,先是储存到缓冲池⾥,然后缓冲池中的数据定期同步到磁盘中,如果系统宕机,可能会丢失数据,系统重启后会读取redo log恢复数据
隔离性:mysql数据库通过MVCC + next-key机制实现了隔离性
⼀致性:以上3⼤特性,保障了事务的⼀致性
Binlog 和 Redo log 的区别是什么,分别是什么⽤?
binlog是⼆进制⽂件,记录了对数据库执⾏更改的所有操作,不包括select、show,因为这两个操作没有对数据本⾝做修改。但是若操作了数据,但是数据没有发⽣变化,也会记录到binlog。常⽤来数据恢复,数据备份。
redo log⼜叫做重做⽇志⽂件,记录了事务的修改,不管事务是否提交都记录下来。在实例和介质失败时,InnoDB存储引擎会使⽤redo log恢复到之前的状态,保证数据的完整性
谈⼀谈 MVCC 多版本并发控制
MVCC是通过在每⾏记录后⾯保存两个隐藏的列来实现的。这两个列,⼀个保存了⾏的创建时间,⼀个保存⾏的过期时间(或删除时间)。当然存储的并不是实际的时间值,⽽是系统版本号(system version number)。每开始⼀个新的事务,系统版本号都会⾃动递增。事务开始时刻的系统版本号会作为事务的版本号,⽤来和查询到的每⾏记录的版本号进⾏⽐较。
SELECT
InnoDB会根据以下两个条件检查每⾏记录:
1. InnoDB只查版本早于当前事务版本的数据⾏(也就是,⾏的系统版本号⼩于或等于事务的系统版本号),这样可以确保事务读取的
⾏,要么是在事务开始前已经存在的,要么是事务⾃⾝插⼊或者修改过的。
2. ⾏的删除版本要么未定义,要么⼤于当前事务版本号。这可以确保事务读取到的⾏,在事务开始之前未被删除。
只有符合上述两个条件的记录,才能返回作为查询结果
INSERT
InnoDB为新插⼊的每⼀⾏保存当前系统版本号作为⾏版本号。
DELETE
InnoDB为删除的每⼀⾏保存当前系统版本号作为⾏删除标识。
UPDATE
InnoDB为插⼊⼀⾏新记录,保存当前系统版本号作为⾏版本号,同时保存当前系统版本号到原来的⾏作为⾏删除标识。
Innodb 和 MyISAM 的区别是什么
1. Innodb ⽀持事务。MyISAM 不⽀持
2. Innodb ⽀持外键。MyISAM 不⽀持
3. Innodb 主键索引的叶⼦节点是数据⽂件,辅助索引的叶⼦节点是主键的值。MyISAM 的主键索引和辅助索引,叶⼦节点都是数据⽂件
的指针
4. Innodb 不保存表的⾏数,执⾏select count(*) from tb需要全表扫描。MyISAM ⽤⼀个变量保存了整个表的⾏数,执⾏上述语句只需要读取
该变量,速度很快
5. Innodb 所有的表在磁盘上保存在⼀个⽂件中。MyISAM 存储成三个⽂件。
6. Innodb 需要更多的内存和存储。MyISAM 可被压缩,存储空间较⼩。
7. Innodb 移植⽅案拷贝⽂件、备份 binlog,或者⽤ mysqldump,移植较困难。MyISAM 数据以⽂件形式存储,在备份和回复时可以单独
针对表进⾏操作
8. Innodb ⽀持⾏锁、表锁。MyISAM ⽀持表锁
9. Innodb 在5.7版本之前不⽀持全⽂索引。MyISAM ⽀持全⽂索引
Innodb 的默认加锁⽅式是什么,是怎么实现的
Innodb默认加锁⽅式是⾏级锁
通过给索引上的索引项加锁来实现的
如何⾼效处理⼤库 DDL
DDL是值数据定义语句,即建表,建视图这种,所以这⾥的问题,我认为可能是考察建表的时候注意事项。
⽐如数据字段的定义,遵循从⼩原则。表的创建,降低耦合。
这道题不是很明⽩,欢迎留⾔讨论。
Mysql 索引重建
1. mysqldump导出然后重新导⼊,drop index + recreate index
2. alter table xxx ENGINE = InnoDB
3. repaire table xxx,这种对于InnoDB的⽆效
4. OPTIMIZE TABLE xxx
对于多列索引,哪些情况下能⽤到索引,哪些情况⽤不到索引
1. like以%开头
2. or查询,必须左右字段都是索引,否则索引失效
3. 联合索引,遵从最左匹配原则,如果不是使⽤第⼀列索引,索引失效
4. 数据出现隐形转换,如varchar字段没加单引号,⾃动转为int类型,会使索引失效
5. 索引字段使⽤not、<>、!=,索引失效
6. 索引字段使⽤函数,索引⽆效
为什么使⽤数据库索引可以提⾼效率,在什么情况下会⽤不到数据库索引?
默认执⾏SQL语句是进⾏全表扫描,遇到匹配条件的就加⼊搜索结果合集。如果有索引,就会先去索引表中⼀次定位到特定值的⾏数,减少遍历匹配的⾏数。索引把⽆序的数据变成了相对有序的数据结构。
什么情况⽤不到数据库索引见上题回答
共享锁和排他锁的使⽤场景
更新、新增、删除默认加排它锁,查询默认不加锁
共享锁,使⽤语法select * from tb lock in share mode,⾃⾝可以读,其他事务也可以读(也可以继续加共享锁),但是其他事务⽆法修改
排它锁,适⽤语法select * from tb for update,⾃⾝可以进⾏增删改查,其他事务⽆法进⾏任何操作
关系型数据库和⾮关系数据库的优缺点
关系型数据库
优点:
1. ⼆维表格,容易理解
2. 操作⽅便
3. 易于维护
4. ⽀持SQL
缺点:
1. 读写性能较差
2. 固定的表结构,不够灵活
3. 应对⾼并发场景,磁盘I/O存在瓶颈
4. 海量数据的读写性能差
⾮关系型数据库
优点:
1. 不需要SQL解析,读写性能⾼
2. 可以使⽤硬盘或者内存作为载体,速度快
3. 基于键值对,数据没有耦合性,⽅便扩展
4. 部署简单
缺点:
1. 不⽀持SQL,增加了学习成本
2. 没有事务
Mysql 什么情况会造成慢查,如何查看慢查询响应时间超过阈值会产⽣慢查询⽇志。⼀般有以下情况会造成查询慢
1. 没有设置索引,或查询没有⽤到索引
2. I/O吞吐量过⼩
3. 内存不⾜
4. ⽹络速度慢
5. 查询的数据量过⼤
6. 锁或者死锁
7. 返回了不必要的⾏或列
8. 查询语句存在问题,需要优化
慢查询⽇志默认是关闭的,如果⾮必要,不要开启,会影响性能。
使⽤SHOW VARIABLES LIKE 'slow_query%';
slow_query_log,慢查询开启关闭状态
slow_query_log_file,慢查询⽇志存储位置,⽤⽂本编辑器打开存储位置的⽂件,查询慢查询
如何处理慢查询,你⼀般是怎么处理慢查询的
1. 把数据、⽇志、索引放到不同的I/O设备上,增加读取速度
2. 纵向、横向分割表,减少表的尺⼨
3. 升级硬件
4. 根据查询条件,建⽴索引,索引优化
5. 提⾼⽹速
6. 扩⼤服务器内存
7. 分库分表
Mysql 中 varchar 和 char 的区别
varchar会根据存储的内容改变长度,char是定长,如果长度不够,则使⽤空格补齐
数据库外键的优缺点
优点:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论