尚硅谷MySQL数据库面试题宝典,mysql面试必考!mysql工作必用!






1,主键(唯一索引)匹配
2.全值匹配(单值匹配)
3.最左前缀匹配
4.范围匹配
5.索扫描
6.全表扫描

oderby 需要条件才排序



MySQL 内部有多个核心模块组成,包括:
- 连接器(Connection Manager):负责处理客户端连接和身份验证等操作。
- 查询处理器(Query Processor):负责解析 SQL 语句、生成执行计划和执行查询,是 MySQL 的核心组件。
- 存储引擎(Storage Engine):负责管理表的数据存储和检索,主要包括 MyISAM、InnoDB、Memory、Archive 等多个不同的存储引擎。
- 事务处理器(Transaction Manager):负责管理事务的提交、回滚和锁定等操作。
- 备份恢复(Backup and Recovery):负责管理 MySQL 数据库的备份和恢复。


.ibd 文件是 InnoDB 存储引擎使用的表空间文件,存储了该表的数据和索引。
与之相对应的是 .frm 文件,该文件存储了该表的元数据信息,包括表结构、列名、列数据类型等信息。
最初的 InnoDB 版本中,.frm 和 .ibd 文件是分离的,这意味着如果用户需要重建表,需要处理两个文件。后来的 InnoDB 版本将 .frm 文件整合到了 .ibd 文件中,使得在重建表时变得更加容易。



假设一个银行系统需要对客户进行转账操作,涉及到两个账户的扣款和存款操作,这时可以采用ACID的特性来保证事务处理的正确性。
在这个过程中,需要满足以下条件:
- 原子性(Atomicity):要么两个账户的扣款和存款都成功,要么全部失败回滚,确保数据的完整性和一致性。
- 一致性(Consistency):在转账的过程中,必须保证两个账户的余额总和不变,即一个账户的扣款金额必须等于另一个账户的存款金额。undolog
- 隔离性(Isolation):多个用户同时进行转账操作时,每个用户的操作应该相互隔离,避免因为并发操作而导致的不一致性问题。
- 持久性(Durability):一旦转账完成,其结果就应该被永久保存在数据库中,并对所有后续对数据的访问和操作都可见。redolog
如果银行系统不能满足以上条件,在并发访问的情况下,很可能会发生数据错误或者数据丢失等问题。因此,ACID特性是保证数据库管理系统正确性的重要保障。
- 原子性:原子性是指一个事务中的所有操作要么全部成功,要么全部失败回滚,从而保证操作的原子性。实现原子性需要使用事务日志机制,将所有事务操作写入到日志中,只有在提交完成后才将变更操作应用到数据库。如果事务执行失败,数据库会利用回滚操作将之前的操作全部撤销。undolog
- 一致性:一致性是指保证数据在事务执行前后都满足完整性约束条件,保证数据的正确性。实现一致性可以通过应用程序和数据库系统约束条件来进行校验和处理。此外,还可以使用触发器和存储过程等手段来实现一致性。
- 隔离性:隔离性是指多个并发事务之间互不干扰,所见即所得,防止出现脏读、不可重复读、幻读等问题。隔离级别决定了事务的隔离程度,分为读未提交、读已提交、可重复读和串行化四种级别。隔离性的实现可以通过锁机制、**多版本并发控制(MVCC)**等方式来实现。修改丢失
- 持久性:持久性是指一旦事务提交,其所做的修改将永久保存在数据库中,即使数据库系统发生故障也能够恢复。实现持久性需要使用日志机制,将所有变更操作写入到磁盘等非易失性存储器中,保证在数据库系统崩溃后数据能够得到恢复。

(1)脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
(2)丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
(3)不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
(4)幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
不可重复度和幻读区别:
不可重复读针对的是一份数据的修改
幻读针对的是行数修改
不可重复读的重点是修改,幻读的重点在于新增或者删除。
(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务1中的A先生读取自己的工资为 1000的操作还没完成,事务2中的B先生就修改了A的工资为2000,导 致A再读自己的工资时工资变为 2000;这就是不可重复读。
同样的条件, 第1次和第2次读出来的记录数不一样 ):假某工资单表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记录就变为了5条,这样就导致了幻读。

非锁定读 mvcc
可以这样认为,当delete一条记录时,undo log 中会记录一条对应的insert记录,当update一条记录时,它记录一条对应相反的update记录。
过版本链,我们就可以看出事务版本号、表格隐藏的列和undo log它们之间的关系

undo log有什么用途呢?
- 事务回滚时,保证原子性和一致性。
- 用于MVCC快照读。
快照读和当前读

当前读(update、insert、delete 当前读)
Read view 匹配条件规则如下:
- 如果数据事务ID
trx_id < min_limit_id
,表明生成该版本的事务在生成Read View前,已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。 - 如果
trx_id>= max_limit_id
,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。 - 如果
min_limit_id =<trx_id< max_limit_id
,需腰分3种情况讨论
RR隔离级别,当连续两个快照读中出现当前读,并且当前读有其他事务新增的数据,就会出现幻读 因为快照读,所以没加锁,B不会被阻塞
在 REPEATABLE READ 隔离级别下,事务 A 第一次执行普通的 SELECT 语句时生成了一个 ReadView(且在 RR 下只会生成一个 RV),之后事务 B 向 user 表中新插入一条记录并提交。
ReadView 并不能阻止事务 A 执行 UPDATE 或者 DELETE 语句来改动这个新插入的记录(由于事务 B 已经提交,因此改动该记录并不会造成阻塞),但是这样一来,这条新记录的 trx_id
隐藏列的值就变成了事务 A 的事务 id。之后 A 再使用普通的 SELECT 语句去查询这条记录时就可以看到这条记录了,也就可以把这条记录返回给客户端。
因为这个特殊现象的存在,我们也可以认为 MVCC 并不能完全禁止幻读。




RR隔离级别下,加锁的select, update, delete等语句,会使用间隙锁+ 临键锁,锁住索引记录之间的范围,避免范围间插入记录,以避免产生幻影行记录,那就是说RR隔离级别解决了幻读问题???

slow query log
show variables like 'slow_query_log%'





两阶段提交




使用字符串存储日期虽然容易上手,但是存在以下两个问题:
- 字符串占用的空间更大;
- 字符串存储的日期比较效率比较低(逐个字符进行比对),无法用日期相关的API。


高价值



- JOIN的效率高于子查询的情况:
- 当需要检索多个表之间据时,使用JOIN可以更理解查询语句。
- 当需要进行大量的数据过滤、分组和排序时,JOIN通常比子查询更高效,因为它可以利用索引对数据进行更快速的访问和处理。
- 子查询的效率高于JOIN的情况:
- 当需要在多个表中进行复杂的关联和过滤时,使用子查询可能会更加直观和方便。此时,JOIN需要更复杂的查询语句才能实现相同的功能。
- 当要从一个大表中获取少量数据时,使用子查询可能比JOIN更高效。因为JOIN可能会产生更大的中间结果集,而子查询只需要返回所需的行。

COUNT(*)
比COUNT(列名)
更高效。这是因为COUNT(*)
不需要检查具体的列的值,只需要读取表中的行数即可得出结果,而COUNT(列名)
需要先对指定的列进行非NULL值的检查,然后才能计数。
