文档:面试题:MySQL
链接:有道云 笔记
十七、MySql
https://www.cnblogs.com/tangjian07/p/10809996.html
164.数据库的三范式是什么?
- 列不可再分
- 属性都依赖于主键
- 属性不直接依赖与其他非主属性,属性直接依赖与主键。
165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
创建表的类型 innoDb 重启之后会是6(将最大的id放在内存中,重启之后会消失)。没有重启回事8
mylsam 都是8;
166.如何获取当前数据库版本?
show version();
167.说一下 ACID 是什么?
168.char 和 varchar 的区别是什么?
char固定长度、varchar可变长度
char:效率高、占空间、若char(10) 存“abc" 那还多出7个字节(占空间)
169.float 和 double 的区别是什么?
float 8位十进制 占内存4个字节
double16十进制 占内存8个字节
170.mysql 的内连接、左连接、右连接有什么区别?
join 内连接 、left join (左连接) right join (右链接)
内连接显示公共的数据
左连接:左表显示全部,右表显示匹配上的
右连接:相反
171.mysql 索引是怎么实现的?
B+ 树实现,索引就像字典的目录一样,为了提高查询速度。
172.怎么验证 mysql 的索引是否满足需求?
explain
explain select * from table where type=1。
173.说一下数据库的事务隔离?
174.说一下 mysql 常用的引擎?
innodb(默认的)、mylasm
前者:事务支持,提供了行级锁与外键的约束,select count(*)from table是扫描全表,他不会保存表的行数。写操作不会锁表,大大的提升了效率。
后者:在执行新增与插入时,会锁表,降低了效率。不支持事务,没有行级锁、外键约束,select count(*)from table查询的是你新增的那几条数据放在一起、不必要全表扫描。
175.说一下 mysql 的行锁和表锁?
lnondb默认是行锁。mylasm默认锁表
行锁:开销大、加锁慢、会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。
表锁:开销小、加锁快、不会出现锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
176.说一下乐观锁和悲观锁?
https://blog.csdn.net/qq_34337272/article/details/81072874
乐观锁:假设最好的情况,去拿数据的时候认为没有人修改,所以不会上锁。但提交更新的期间判断是否有别人修改这条数据。
悲观锁:假设最坏的情况,去哪数据的时候认为别人会修改,所以每次拿数据的时候都会上锁。这样别人想拿这条数据阻止他,直到锁被释放。
乐观锁:版本号机制
假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。当需要对账户信息表进行更新的时候,需要首先读取version字段。
- 操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 $50( $100-$50 )。
- 在操作员 A 操作的过程中,操作员B 也读入此用户信息( version=1 ),并从其帐户余额中扣除 $20 ( $100-$20 )。
- 操作员 A 完成了修改工作,提交更新之前会先看数据库的版本和自己读取到的版本是否一致,一致的话,就会将数据版本号加1( version=2 ),连同帐户扣除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
- 操作员 B 完成了操作,提交更新之前会先看数据库的版本和自己读取到的版本是否一致,但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,而自己读取到的版本号为1 ,不满足 “ 当前最后更新的version与操作员第一次读取的版本号相等 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。
177.mysql 问题排查都有哪些手段?
- 使用 show processlist 命令查看当前所有连接信息。
- 使用 explain 命令查询 SQL 语句执行计划。
- 开启慢查询日志,查看慢查询的 SQL。
178.如何做 mysql 的性能优化?https://www.cnblogs.com/pengyunjing/p/6591660.html
-
- 经常搜索的字段加上索引
- 尽量避免Select *
- 正确选择引擎
- 查一行数据就用limit 1
- 在join表连接的时候,连接的字段,加上索引。
// 在state中查找company
"SELECT company_name FROM users
LEFT JOIN companies ON (users.state = companies.state)
WHERE users.id = $user_id"
// 两个 state 字段应该是被建过索引的,而且应该是相同的类型,相同的字符集。
为每一张表设置一个id
- 枚举类型尽量使用enum类型不要使用varChar
- 字段设置为not null
- 所有的字段都要有固定的长度