前言
题目汇总来源 史上最全各类面试题汇总,没有之一,不接受反驳
目录
请简洁描述Mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?
Mysql 的存储引擎 myisam 和 innodb 的区别。
乐观锁和悲观锁是什么,INNODB的标准行级锁有哪2种,解释其含义。
数据库
请简洁描述Mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?
不可重复读侧重的是对数据的修改,而幻读侧重的是对数据的增加和删除;解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
在Mysql中ENUM的用法是什么?
enum 在数据库底层以整型方式储存,从 1 开始,0 用于指代空或错误的字符串。
CREATE TABLE student(
id INT(11) PRIMARY key auto_increment,
name VARCHAR(10) not null,
sex ENUM('boy','girl','secret') DEFAULT 'secret'
)ENGINE=INNODB
SELECT * FROM student WHERE sex=[1|'boy'];
CHAR和VARCHAR的区别?
char 固定长度 255,不足的部分补空格,取出时再去掉空格。
varchar 不定长度。
事务是如何通过日志来实现的,说得越深入越好
redo和undo。
基本流程如下:
因为事务在修改页时,要先记 undo,在记 undo 之前要记 undo 的 redo, 然后修改数据页,再记数据页修改的 redo。 Redo(里面包括 undo 的修改) 一定要比数据页先持久化到磁盘。 当事务需要回滚时,因为有 undo,可以把数据页回滚到前镜像的状态,崩溃恢复时,如果 redo log 中事务没有对应的 commit 记录,那么需要用 undo把该事务的修改回滚到事务开始之前。 如果有 commit 记录,就用 redo 前滚到该事务完成时并提交掉。
drop,delete与truncate的区别
drop,delete与truncate的区别(删除表的方式,哪个快)
drop 删表,delete 删表中的数据,truncate 清空表。
truncate、drop 是DDL,不记入日志,不能回滚;delete 是 DML,记入日志,能回滚
局部性原理与磁盘预读
由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。
由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。
预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页的大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。
数据库范式
第一范式
如果一个关系模式的所有属性的域都是原子的,称这个关系模式属于第一范式。关系中每一分量不可再分。
不能以集合、序列等作为属性值。
sdudent_number | course_number |
---|---|
s1 | {c1,c2,c3} |
sdudent_number | course_number |
---|---|
s1 | c1 |
s1 | c2 |
s1 | c3 |
第二范式
一个关系模式满足第一范式的前提下,且每个属性满足以下条件之一:
- 它出现在一个候选码之中;
- 它没有部分依赖于某候选码;
称之为第二范式。
消除非主属性对码的部分依赖。
// 不满足第二范式
// 学号,学生姓名,学院编号,学院,课程编号,分数
关系模式 S(sno , sname, dno , dean , cno, score)
主码 (sno, cno)
(sno,cno) -p-> sname
(sno,cno) -p-> dno
// 满足第二范式
SC(sno , cno , score)
S_SD(sno , sname ,dno , dean)
第三范式
满足第二范式,消除非主属性对码的传递依赖。
// 不满足第三范式
S_SD(sno , sname ,dno , dean)
sno -> dno -> dean
// 满足第三范式
S (sno , sname , dno)
D (dno , dean)
BCNF
满足3NF,消除每一属性对候选键的传递依赖。
存储过程与触发器的区别
触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发(激活)执行。触发器是在一个修改了指定表中的数据时执行的存储过程。通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。触发器不同于存储过程,触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。
锁的优化策略
为什么Mysql用B+树做索引而不用B树
B树与B+树的区别:
- B树每个索引节点都可以存放数据;B+树非叶节点只存放索引,仅在叶节点存放数据。
为什么使用B+树:
- B树节点既存放索引也存放数据,想要定位数据要进行更多次磁盘I/O;B+树索引节点仅存放索引,能快速定位数据,减少I/O次数。
- B+树叶节点可以使用指针串联,方便遍历和范围查找。
为什么不使用平衡二叉树或红黑树:
- 磁盘I/O次数与树深度有关,B树比二叉树深度低,I/O次数更少。
B树/B+树插入删除
什么情况下设置了索引但无法使用
MYSQL 索引类型、什么情况下用不上索引、什么情况下不推荐使用索引
- 条件中使用了 or,而相关列不全有索引
- 条件中使用了and,而相关列不满足最左原则
- 索引列的数据类型出现隐形转换
- like查询是以%开头
- where 子句里对索引列上有数学运算/函数
- mysql估计使用全表扫描要比使用索引快
什么情况下不宜建立索引?
- 数据唯一性差(一个字段的取值只有几种时)的字段不要使用索引
- 频繁更新的字段不要使用索引
- 字段不在where语句出现时不要添加索引,如果where后含IS NULL /IS NOT NULL/ like ‘%输入符%’等条件,不建议使用索引
- where 子句里对索引列使用不等于(<>),使用索引效果一般
解释MySQL外连接、内连接与自然连接的区别
外连接
左连接:连接两张表,左表数据完全显示,右表匹配,匹配不上的补null;
右连接:同上,换个方向;
全外连接:两表字段都匹配,匹配不上的补null;
内连接
所有查询出的结果都是能够在连接的表中有对应记录的。
自然连接
找到两表的公共字段,然后和内连接一样。
完整性约束包括哪些?
其他说法:
- 主键,外键,唯一,检查,默认
- 主键,外键,唯一,检查,非空
MySql不支持check
Mysql 的存储引擎 myisam 和 innodb 的区别。
MySQL两种存储引擎: MyISAM和InnoDB 简单总结
myisam | innodb | |
---|---|---|
事务支持 | 不支持 | 支持 |
存储结构 | 三种文件 | 一种文件 |
存储空间 | 体积小 | 体积大 |
可移植性 | 方便 | 困难 |
锁力度 | 表级锁 | 表级锁,行级锁 |
全文索引 | 支持 | 不支持 |
表主键 | 可以没有 | 必须有,没有就自动生成 |
外键 | 不支持 | 支持 |
如何进行SQL优化
首先参考上面的“索引失效”,尽可能在查询时利用到索引。
其他有一些细碎的优化方式,比如:
- exists 代替 in
- 不要过多建索引,会降低插入和更新效率
- 少用 select *
- varchar 代替 char
- 不频繁创建临时表
乐观锁和悲观锁是什么,INNODB的标准行级锁有哪2种,解释其含义。
悲观锁
悲观锁,也叫悲观并发控制,当事务A对某行数据应用了锁,并且当这个事务把锁释放后,其他事务才能够执行与该锁冲突的操作,这里事务A所施加的锁就叫悲观锁。
MySql 中悲观锁的实现:
select … for update
乐观锁
乐观锁,也叫乐观并发控制,它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,那么当前正在提交的事务会进行回滚。
MySql 中乐观锁需要手写逻辑:
SELECT data AS old_data, version AS old_version FROM …;
// 根据获取的数据进行业务操作,得到new_data和new_version
UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
// 乐观锁获取成功,操作完成
} else {
// 乐观锁获取失败,回滚并重试
}
标准行级锁
- 共享锁(S Lock):允许事务读取一行数据。
- 排他锁(X Lock):允许事务更新或删除一行数据。
| X 排它锁 | S 共享锁 |
X 排它锁 | 冲突 | 冲突 |
S 共享锁 | 冲突 | 兼容 |
补充:意向锁
- 意向共享锁(IS Lock):事务想要获得一张表中某几行的共享锁
- 意向排他锁(IX Lock):事务想要获得一张表中某几行的排他锁
| X 排它锁 | S 共享锁 | IX 意向排它锁 | IS 意向共享锁 |
X 排它锁 | 冲突 | 冲突 | 冲突 | 冲突 |
S 共享锁 | 冲突 | 兼容 | 冲突 | 兼容 |
IX 意向排它锁 | 冲突 | 冲突 | 兼容 | 兼容 |
IS 意向共享锁 | 冲突 | 兼容 | 兼容 | 兼容 |
MVCC的含义,如何实现的
MVCC是一种多版本并发控制机制。MVCC是通过保存数据在某个时间点的快照来实现的。
在每个表后添加创建版本号和删除版本号,版本号为修改该项的事务版本号。
读取只能读取创建版本号小于该事务版本号以及无删除版本号或删除版本号大于事务版本号的项。
update操作将就数据标记为删除,插入相同的新数据有新创建版本号。
MYSQL的主从延迟怎么解决。