系列综述:
💞目的:本系列是个人整理为了秋招面试
的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于拓跋阿秀、小林coding等大佬博客进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞和关注一下呗,谢谢🎈🎄🌷!!!
🌈【C++】秋招&实习面经汇总篇
ACID事务模型
的数据库,采用表格形式
存储数据,通过表格中的关系连接
实现数据的查询和管理。
BASE模型
的数据库,采用多种形式
存储数据,通过分布式计算技术
实现高可扩展性、高性能和高可用性
长连接
*
修改配置文件
中的默认连接超时时间,通过心跳机制
定义维护或连接池
进行管理连接// 短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)
// 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql
....
断开 mysql 服务(TCP 四次挥手)
/var/lib/mysql/ 自定义数据库名
目录下
.ibd
的结构
总结:
数据库的数据部分,由存放再磁盘上的三个文件组成:存储字符集和字符校验规则的.opt文件、存储表结构的.frm文件、存储表空间数据的.ibd文件。存储表空间数据的.ibd文件有四个层次,分为为段、区、页、行,其中,段有三种,一个是存放 B + 树的非叶子节点的区集合的索引段,第二个是存放 B + 树的叶子节点的区集合的数据段,第三个是存放的是回滚数据的区集合回滚段。每个区由64个物理地址连续的物理页构成,可以提高磁盘范围查询的顺序IO性能。每个页默认为innodb一次读写的单位16KB。每个行存储一条数据记录,不同记录具有不同的行格式。
范围查询WHERE
、分组查询GROUP BY 和 按属性排序ORDER BY
由非叶子结点组成
的多路平衡查找树
用于快速的随机查找
操作由叶子结点组成
的按主键顺序的双链表
用于高效的数据的增删操作
和基于范围的顺序查找
多路
表示是一棵多叉树(m>2),每个非叶子结点由两部分组成
按主键顺序的子节点索引链表
:每个子节点索引指向一个子节点,且索引结点键值等于索引子节点的最小键值(类似目录查找)。最大和最小键值
:主要用于快速定位和过滤查询请求的。平衡
表示B+树的每个子树的高度是相等的,尽可能“矮胖”查找
表示B+树的快速查找能力较强。
相比B树,非叶子结点不存放数据
:可以存放更多的索引,使得树更加“矮胖”,极大减少比较耗时的I/O操作。搜索复杂度为$O(log_dN)$
:当最大分支数d大于100时,千万级数据量的查询操作也只需做 3~4
次的磁盘 I/O 操作,即树的高度只有3~4层
。页目录由槽组成
,索引数据记录分组。数据记录分组由数据记录组成
,按主键顺序存储可由二分法进行查找。按指定键顺序进行双链表链接
。可以高效满足数据的增删操作
和基于范围的顺序查找
索引和数据存储在一起
,在一个表中只能有一个聚集索引索引和数据都是单独存储
,需要通过索引找到数据行联合索引
:建立在多列上的索引,遵循最左匹配原则
函数和计算
否定操作符
使用or
进行条件连接含NULL值列
查询条件左右两侧类型不匹配
的时候会发生隐式转换like "%value"
匹配值第一个为%,会导致全表查询复合索引遵守最左匹配原则
,索引字段最好按区分度排序Innodb 的回滚日志(undo log)
用于记录事务执行的反向操作
undo log必须先于数据持久化到磁盘
(谋而后动),优先保证回滚日志的完整性四种隔离级别
保证事务的隔离
锁机制
保证数据的访问隔离
MVCC(多版本并发控制
)保证并发的访问隔离
执行中事务的修改操作
,用于事务回滚的撤销操作已提交事务的修改操作
(循环区满会被覆盖),用于短时的故障恢复所有已提交事务的修改操作
(通常来源于重做日志),用于完整的数据恢复和主从复制未提交读(read uncommitted)
提交读(read committed)
修改前先获取写锁
,并将修改保存到事务日志中,然后再提交,从而保证其他事务只能读取已经提交的事务所修改的数据。可重复读(repeatable read)
读写锁
共享访问数据,事务修改数据前要使用写锁,保证其他事务无法同时修改数据。事务读取数据前加一个读锁,保证其他事务无法修改数据串行化(serializable )
脏读
:A事务执行更新数据操作后发生了回滚,而B事务读到了更新后的数据,但是由于A事务的回滚,导致B事务读取数据和数据库中的不一致。不可重复读
:事务针对同一条记录
的前后两次读取结果不同幻读
:事务对于一条查询语句
的前后两次执行结果不同flush tables with read lock
加锁,会话结束或者执行unlock tables
会自动释放数据
的修改操作,比如 insert、delete、update等语句;表结构
的修改操作,比如 alter table、drop table 等语句。一条记录
的读写锁一个范围
的读写锁锁定一个范围,并且锁定记录本身
未提交事务在数据库中的修改操作
,若发生数据库崩溃
或执行ROLLBACK语句
,通过undo log将数据库恢复到事务开始前的状态。插入
记录时,存储记录的主键
,回滚时只需要删除主键对应的记录删除
记录时,存储记录的全部内容
,回滚时将该记录再插入更新
记录时,存储记录的旧值
,回滚时再更新为旧值数据版本链
保存事务对数据记录修改的多个版本,每个事务通过隔离级别
和快照时间
选择合适的版本读取。已提交事务的所有修改操作
,当数据库发生故障时,系统会将重做日志中的操作重新执行,进行crash-safe(崩溃恢复),避免内存断电导致未刷盘的数据丢失写满时
将最早写入的记录刷盘并覆盖
innodb_log_Buffer_size 参数
增加redo log容量(默认16 MB) 正常关闭
时;大于
redo log buffer 内存空间的一半
时,会触发落盘;每隔 1 秒
,将 redo log buffer 持久化到磁盘。事务提交
时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘binlog_cache_size 参数
控制,超过缓存大小就要暂存到磁盘。故意等待,成组提交
来实现的,因此可能会增加语句的响应时间,但即使 MySQL 进程中途挂了,也没有丢失数据的风险,因为 binlog 早被写入到 page cache 了,只要系统没有宕机,缓存在 page cache 里的 binlog 就会被持久化到磁盘。写入内核缓冲区,异步提交
将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000),表示每次提交事务都 write,但累积 N 个事务后才 fsync,相当于延迟了 binlog 刷盘的时机。但是这样做的风险是,主机掉电时会丢 N 个事务的 binlog 日志。详细解释:MySQL中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到Buffer Pool中。后续的查询都是先从Buffer Pool中找,没有命中再去硬盘加载(page fault?),减少硬盘IO开销,提升性能。更新表数据的时候,也是如此,发现Buffer Pool里存在要更新的数据,就直接在Buffer Pool里更新。然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到redo log文件里。
以页为基本单位
进行磁盘和内存的交互,一个页的默认大小为 16KB。默认配置
下为128MB
,并默认以16KB为单位大小划分缓冲页。可通过调整innodb_buffer_pool_size
参数来设置 Buffer Pool 的大小,一般建议设置成可用物理内存的 70%左右整个数据页
加载到Buffer Pool中,通过索引你定位到具体数据页,再使用页目录定位具体的数据记录先查缓存,命中再去磁盘读
)合适的时机
将脏页刷盘。空闲缓冲页的控制块的索引
的双链表脏页的控制块的索引
的双链表,后台线程就可以遍历 Flush 链表,将脏页写入到磁盘即将访问的页
移动到链表头部,如果该页不在链表中,则淘汰链表末尾页redo log 日志
满了的情况下,会主动触发脏页刷新到磁盘;Buffer Pool 空间不足
时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;空闲时
,后台线程会定期将适量的脏页刷入到磁盘;正常关闭
之前,会把所有的脏页刷入到磁盘;哈希表
实现单条记录
的快速查询B+树
组织索引值,实现任意数据记录
的查询