资讯动态

Java高级后端 · 全套面试通关手册(MySQL)

发布时间:2026/10/1 6:44:01 来源:尧图企业网站定制
存储引擎默认 InnoDB支持事务、MVCC、行锁MyISAM 不支持事务只有表锁。一、MySQL 锁体系重点1.锁粒度(1)表锁锁定整张表。MyISAM 默认表锁开销小锁粒度大并发差。读锁共享写锁排他。(2)行锁InnoDB锁单行记录。粒度小并发高开销大容易死锁。行锁是基于索引实现如果不走索引行锁退化为表锁。(3)意向锁Intention Lock表级别的意向共享 IS、意向排他 IX。 作用标记表里有行锁存在。当要加表锁时通过意向锁快速判断表内是否存在行锁不用遍历所有行。意向锁之间互相兼容意向锁和表读写锁互斥。2.行锁分类共享锁 S读锁多个事务可以同时加 S 锁不能写。select ... lock in share mode排他锁 X写锁只有持有锁事务可读可写其他事务读写都阻塞。select ... for update3.Gap Lock 间隙锁⭐高频锁定索引记录之间的间隙防止幻读。只在 RR可重复读隔离级别存在。锁住的是索引间隙不是物理记录。4.Next-Key Lock临键锁Next-Key Record Lock 记录锁 Gap 间隙锁InnoDB RR 默认行锁算法左开右闭区间。当索引唯一且精准命中一条记录时临键锁退化成记录锁。5.幻读同一事务内多次查询查到别的事务新插入的数据。RR 依靠 MVCC 临键锁解决幻读。6.死锁多个事务互相持有对方需要的锁循环等待。产生 4 条件互斥、持有并等待、不可剥夺、循环等待。InnoDB 自动检测死锁回滚代价小的事务。避免方案统一资源访问顺序减少事务粒度避免 for update 非索引字段。二、事务隔离级别 MVCC顺带回顾1.读未提交 RU2. 读已提交 RC3. 可重复读 RRMySQL 默认4. 串行化。RC无间隙锁每次 select 读取最新快照。存在幻读。RRMVCC Next-key 锁解决幻读。 MVCC 核心版本链 Read View。每行记录多个版本 undo log事务根据 ReadView 选择可见版本。三、SQL 调优高频考点(1)Explain 执行计划关键字段id执行顺序select_typeSIMPLE 简单查询SUBQUERY 子查询type最重要性能从好到坏systemconsteq_refrefrangeindexALL目标至少 range尽量 refALL 是全表扫描必须优化key实际使用索引key_len索引占用字节rows预估扫描行数Extra Using filesort文件排序没用到索引排序需要优化 Using temporary临时表常见 group by 无索引 Using index覆盖索引性能很好(2)索引失效场景背诵索引列做运算、函数、隐式类型转换最左前缀原则破坏联合索引跳过左边字段like % xxx 左模糊or 连接一侧无索引MySQL 优化器判断全表扫描比索引更快主动放弃索引(3)索引设计原则联合索引遵循最左前缀匹配区分度高字段放前面尽量覆盖索引避免回表回表主键索引找到主键再去主键树查询完整数据索引不宜过多索引提升查询降低写入性能写需要维护索引 B 树字符串索引可以前缀索引InnoDB 主键索引是聚簇索引数据存在叶子节点二级索引叶子存放主键。四、数据库参数 业务层面调优buffer_poolInnoDB 核心缓存缓存页数据热点数据放内存。生产设服务器内存 50%~70%。redo log崩溃恢复事务预写日志。redo log buffer 刷盘策略 innodb_flush_log_at_trx_commit。 1每次事务提交刷盘默认安全0 每秒刷2 提交写到 os buffer。undo log版本链实现 MVCC存放旧数据版本。慢查询slow_query_loglong_query_time抓取慢 SQL 优化。五、高频深挖面试题Q1行锁什么时候降级表锁where 条件没有索引InnoDB 无法定位行行锁退化成表锁。Q2RC 为什么没有间隙锁RC 隔离级别不需要防止幻读关闭 gap 锁只使用记录锁并发更高。Q3覆盖索引是什么查询字段全部在索引里面不需要回表。Extra 出现 Using index。Q4幻读、不可重复读区别不可重复读同一事务其他事务修改 / 删除已有数据。 幻读其他事务插入新记录读到新行。Q5redo log 和 undo log 区别redo log保证崩溃恢复物理日志持久化。 undo log逻辑日志保存旧版本实现 MVCC、事务回滚。一句话背诵总结InnoDB 行锁基于索引无索引退表锁RR 隔离级别默认 Next-Key 临键锁记录锁 间隙锁解决幻读意向锁用于快速判断表内是否存在行锁Explain 看 type 和 Extra规避索引失效MVCC 依靠 undo 版本链 ReadView调优优先优化 SQL 索引合理设置 buffer_pool 与 redo 刷盘参数。六、MySQL 事务 MVCCInnoDB 引擎支持事务事务四大特性 ACIDMVCC 是 InnoDB 实现隔离级别的核心机制。一、事务 ACIDA 原子性 Atomicity事务是最小单元要么全部成功要么全部失败。依靠 undo log 实现。C 一致性 Consistency事务执行前后数据完整性不变约束、业务规则不变是最终目标。I 隔离性 Isolation多个并发事务之间相互隔离。依靠锁 MVCC 实现。D 持久性 Durability事务提交后修改永久保存宕机不丢失。依靠 redo log 实现。二、4 种事务隔离级别由低到高读未提交 RU能读到其他事务未提交数据。问题脏读。几乎不用。读已提交 RC只能读到别人已经提交的数据。解决脏读存在不可重复读、幻读。可重复读 RRMySQL InnoDB 默认同一个事务内多次读取同一数据结果一致。解决脏读、不可重复读依靠 MVCC 临键锁解决幻读。串行化 Serializable最高级别读加共享锁写加排他锁。完全无并发问题性能极差。三大读问题脏读读到其他事务未提交的数据。RU 才有。不可重复读同一事务两次读同一行中间别的事务修改并提交两次结果不一样。侧重修改、删除。幻读同一事务多次范围查询别的事务插入新数据读到新行。侧重新增记录。区分口诀不可重复读是行数据被改幻读是多出来新行。三、MVCC 多版本并发控制⭐核心考点MVCC 全称 Multi-Version Concurrency Control不加锁实现读提升并发。InnoDB 的普通快照读select走 MVCC当前读select ... for update /lock in share mode走锁机制。(1)核心组件1.undo log 回滚日志记录数据修改前的旧版本形成版本链。一条记录多次修改多个版本串联成链表。 undo log 用来回滚事务 构建版本链实现 MVCC。2.Read View 读视图事务快照决定当前事务能看到哪些版本数据。ReadView 核心 4 个字段m_id当前事务 IDm_low_limit_id下一个未分配事务 idm_up_limit_id活跃事务最小 idm_ids创建视图时所有活跃未提交事务 ID 集合可见性判断规则背诵版本事务 ID m_up_limit_id → 可见版本事务 ID m_low_limit_id → 不可见事务 ID 在 m_ids 集合内 → 不可见其他情况跳到版本链上一条旧版本继续判断(2)RC 和 RR 下 ReadView 创建时机RC读已提交每次 select 都会生成新 ReadView。每次查询都拿最新快照可以看到别的事务已提交修改。存在不可重复读。RR可重复读事务中第一次 select 才创建 ReadView整个事务复用这一个视图。整个事务快照不变保证可重复读。MySQL RR 级别MVCC 只能避免快照读的幻读当前读的幻读需要 Next-Key 临键锁解决。四、快照读 vs 当前读必考区分(1)快照读普通 select读取快照版本不加锁走 MVCC。(2)当前读读取最新数据加行锁。语句select ... for update、select ... lock in share mode、update、delete、insert。五、高频深挖面试题Q1MVCC 怎么实现可重复读RR 事务第一次 select 生成 ReadView后续查询复用这个 ReadView版本链数据不变保证多次读取结果一致。Q2redo log 和 undo log 区别redo log保证持久性崩溃恢复物理日志事务提交刷盘。 undo log保证原子性、MVCC保存旧数据版本逻辑日志。Q3MVCC 有没有锁快照读无锁当前读依旧要加行锁。MVCC 不是替代锁二者配合。Q4RR 可以完全杜绝幻读吗快照读MVCC 避免幻读 当前读依靠 Next-key 临键锁锁住间隙防止其他事务插入新数据杜绝幻读。二者配合。Q5为什么 RC 没有间隙锁RC 隔离级别不需要解决幻读关闭 Gap 锁只有记录锁并发更高。一句话背诵总结事务 ACIDundo 保证原子redo 保证持久MVCC 锁实现隔离4 隔离级别 RU/RC/RR/ 串行脏读、不可重复读、幻读MVCC 依靠 undo 版本链 ReadViewRR 首次 select 生成 ReadViewRC 每次 select 新建快照读走 MVCC 不加锁当前读加行锁RR 通过 MVCC 临键锁解决幻读。七、MySQL B 树索引原理InnoDB 索引底层采用 B 树聚簇索引设计是面试核心。B 树、B 树是多路平衡查找树不是二叉树。一、B 树特点对比 B 树所有数据都存叶子节点非叶子节点只存索引键 子节点指针不存完整数据。叶子节点通过双向链表串联有序范围查询极强。所有查找最终都会落到叶子节点。非叶子节点仅做索引导航树高度低IO 次数少。B 树每个节点都存 key 数据范围查询差。二、聚簇索引 二级索引⭐高频(1)聚簇索引主键索引InnoDB主键就是聚簇索引。整张表数据直接放在主键 B 树叶子节点。叶子节点主键 完整行数据。一张表只能有一个聚簇索引。没有主键InnoDB 选唯一非空索引都没有自动生成隐藏 rowid 作为聚簇索引。(2)二级索引普通索引叶子节点索引列的值 主键值不存储整行数据。查询流程先在二级索引找到主键再拿主键去聚簇索引查询完整数据这个过程叫回表。覆盖索引查询字段全部在二级索引叶子节点不需要回表。Explain 出现 Using index。三、索引页结构B 树节点默认一页 16KB。一页可以存放大量索引 key所以 B 树高度很低。 百万级数据B 树高度一般 2~3 层。一次磁盘 IO 读取一页查询最多 2~3 次磁盘 IO。四、最左前缀原则联合索引联合索引index(a,b,c)索引按 a→b→c 排序。规则从左向右匹配遇到范围查询 between like就停止匹配。有效where a?where a? and b?where a? and b? and c?失效where b?跳过最左 awhere a? and b?b 后面字段失效。等值放前面范围放最后。五、索引分类补充主键索引唯一非空聚簇索引。唯一索引索引值唯一可以 null。普通索引无唯一性约束。联合索引多个字段组合索引。前缀索引长字符串取前 N 个字符建立索引节省空间。六、高频深挖面试题Q1为什么不用二叉搜索树 / 红黑树做数据库索引二叉树深度高大数据量下磁盘 IO 次数太多红黑树是二叉树节点少深度依然远高于 B 树。B 树一页存大量 key树矮IO 少。Q2为什么 B 树叶子节点用双向链表范围查询、排序直接遍历链表不需要中序遍历性能高分页查询友好。Q3为什么二级索引存主键而不是物理地址如果存物理地址主键更新、页分裂会导致大量索引维护。主键稳定聚簇索引页移动不影响二级索引。Q4页分裂、页合并页满插入新数据会分裂成新页叫页分裂影响性能 删除数据页面空闲空间太多触发页合并。减少页分裂主键尽量自增随机主键uuid容易频繁页分裂。Q5为什么推荐自增主键自增主键有序写入在 B 树末尾追加几乎不会触发页分裂UUID 无序随机插入频繁页分裂IO 压力大。一句话背诵总结InnoDB 索引底层 B 树非叶子节点只存索引 key叶子节点存放数据聚簇索引叶子是完整行二级索引叶子存主键查询需要回表联合索引遵守最左前缀自增主键减少页分裂B 树链表优化范围查询。八、MySQL redo log、undo log、binlog三大日志是 InnoDB 事务、崩溃恢复、主从复制核心高频对比提问。一、redo log重做日志作用保证事务持久性实现崩溃恢复。落盘思路WAL 预写日志先写日志再刷数据页。写入流程事务修改数据页先写 redo log buffer事务提交时redo 写入 os cache根据innodb_flush_log_at_trx_commit决定是否刷磁盘。数据库宕机利用 redo log 把已经提交事务的数据恢复到磁盘。性质物理日志记录 “某个数据页被改成什么内容”。文件固定大小环形文件组ib_logfile0、ib_logfile1循环复用。innodb_flush_log_at_trx_commit三值1默认事务提交redo log 刷磁盘。最安全性能略低。0每秒刷盘事务提交不刷。宕机丢 1s 数据。2事务提交写入系统缓存每秒刷盘。宕机可能丢系统缓存内数据。二、undo log回滚日志作用①事务原子性失败时回滚②构建版本链支撑 MVCC 实现快照读。性质逻辑日志记录数据修改前旧版本。不是物理页还原是反向操作insert 对应 deleteupdate 反向 update。生命周期事务提交不会立刻删除 undoMVCC 还有事务需要读取旧版本时undo 保留没有事务依赖后后台 purge 线程清理。redo 是存修改后的数据undo 存修改前旧数据。三、binlog二进制日志作用MySQL 服务层面日志用于主从复制、数据备份恢复。不属于 InnoDB是 Server 层日志。性质逻辑日志记录 SQL 语句 / 行变更记录执行成功后的事件。三种格式statement记录原始 SQL日志体积小函数、随机函数可能主从不一致。row生产推荐记录行数据变更不依赖 SQL主从数据一致日志量大。mixed混合模式自动选择 statement/row。写入时机事务提交阶段写入 binlog cache提交后刷入 binlog 文件。文件不断追加不会循环覆盖。四、两阶段提交2PC必考redo binlog目的保证 redo log 和 binlog 数据一致防止主从数据不一致。Prepare 阶段写 redo log状态标记 preparebinlog 写入 cache不提交。Commit 阶段binlog 持久化磁盘redo log 标记 commit。 崩溃恢复判断redo prepare并且 binlog 完整commit 事务redo preparebinlog 缺失回滚事务参数sync_binlogsync_binlog1每次事务提交 binlog 刷盘保证主从安全。 生产组合innodb_flush_log_at_trx_commit1sync_binlog1ACID 最强性能损耗大。五、三大日志对比速记redo logInnoDB 引擎、物理日志、崩溃恢复、环形复用、WAL。undo logInnoDB 引擎、逻辑日志、回滚 MVCC。binlogMySQL Server 层、逻辑日志、主从复制 备份、追加写入。高频深挖面试题Q1redo 和 binlog 区别redo 属于 InnoDB物理日志崩溃恢复循环写binlog 是 server 层逻辑日志主从备份追加写。2PC 保证两者一致。Q2为什么需要 2PC如果先写 redo 再写 binlogredo 成功binlog 写失败。崩溃恢复后事务提交但是从库没有 binlog主从不一致。 反过来先 binlog 后 redobinlog 成功redo 崩溃没写入。主库回滚从库执行 binlog主从不一致。两阶段提交解决这个问题。Q3binlog 和 undo log 区别binlog 记录修改后的事件用于备份主从undo 记录修改前旧版本用于回滚和 MVCC。Q4redo log buffer 什么时候刷盘事务提交、buffer 满、后台线程定时刷盘。Q5如果宕机发生在 prepare 之后commit 之前会怎么样MySQL 崩溃恢复时检查 binlog 是否完整。binlog 完整则提交binlog 不完整则回滚。一句话背诵总结redo log 是 InnoDB 物理日志WAL 实现崩溃恢复undo log 保存旧版本支持事务回滚和 MVCCbinlog 是 server 层逻辑日志用于主从复制和备份两阶段提交 2PC 保证 redo 和 binlog 一致性保障主从数据统一。九、MySQL 主从复制核心作用读写分离、数据备份、故障切换默认异步复制存在数据不一致风险。一、主从复制基础架构Master 主库负责写同时记录 binlog。Slave 从库拉取主库 binlog回放执行保持数据同步。 从库包含 3 个核心线程IO 线程和主库建立连接读取主库 binlog写入本地 relay log中继日志。SQL 线程读取本地 relay log解析并执行日志里的 SQL落地数据。MySQL8.0 后SQL 单线程瓶颈优化为并行复制。二、完整复制流程Master 开启 binlog所有 DML/DDL 操作写入 binlog。Slave 的 IO 线程连接 Master请求指定位置之后的 binlog。Master 启动 dump 线程推送 binlog 事件给 Slave IO 线程。IO 线程接收 binlog写入本机 relay log 中继日志。Slave 的 SQL 线程读取 relay log解析执行同步数据。从库记录已经同步到的 binlog 位置下次断点续传。三、复制模式3 种⭐高频1.异步复制默认主库写完 binlog 直接返回客户端不等待从库同步。优点性能高缺点主库宕机binlog 还没传到从库数据丢失。2.半同步复制semi-sync主库提交后等待至少一台从库接收 binlog 并 ack 确认再返回客户端成功。不是等从库执行完只是等从库收到日志。优点降低丢数据风险缺点有等待延迟性能下降。 两个超时分支超时自动降级为异步。3.并行复制解决老版本 SQL 单线程回放 relay log主从延迟大的问题。原理同一事务组的事务可以并行回放。MySQL8.0 增强。四、binlog 三种格式回顾主从重点statement记录 SQL 语句日志小函数、rand () 等场景主从数据不一致。row生产推荐记录行变更不依赖 SQL 上下文主从一致性强日志体积更大。mixed混合模式自动选择 statement/row。五、主从延迟面试高频产生原因主库写入并发高从库 SQL 线程回放速度跟不上旧版本单线程回放。从库硬件弱、索引缺失大事务大批量 update。网络延迟大 binlog 传输慢。主库大事务binlog 一次性推送从库长时间执行。解决方案开启并行复制提升从库回放能力优化大事务拆分事务避免一次性生成超大 binlog主从硬件匹配从库建好索引选用 row 格式 binlog网络优化业务规避不要在从库跑大量复杂查询抢占资源六、主从数据不一致场景主从复制延迟查询从库读到旧数据异步复制主宕机切换部分 binlog 未同步从库人为写入数据禁止从库写binlog 格式问题statement 模式下非确定性函数七、GTID全局事务 ID⭐重点GTIDGlobal Transaction ID全局唯一事务编号uuid:事务号。作用主从切换时不用手动找 binlog 文件名 position自动定位同步位点。保证同一个事务只在从库执行一次防止重复回放。故障切换场景GTID 极大简化运维。高频深挖面试题Q1relaylog 是什么中继日志从库 IO 线程拿到主库 binlog先存 relaylogSQL 线程读取 relaylog 执行。防止 IO 和 SQL 线程耦合。Q2半同步复制主库等待从库什么 ack等待从库接收 binlog 写入 relaylog 成功不是等 SQL 线程执行完成。Q3读写分离有什么坑主从延迟写之后立刻查从库读不到最新数据。方案强一致性查询直接查主库。Q4主从复制是同步 redo 还是 binlog同步 binlog。主从复制是 MySQL Server 层机制基于 binlog和 InnoDB redo log 无关。Q5主库宕机怎么选新主优先选择已经同步最多 binlog的从库减少数据丢失。一句话背诵总结主从复制依靠 binlog主库 dump 线程推送 binlog从库 IO 线程写入 relaylogSQL 线程回放分为异步、半同步、并行复制异步可能丢数据主从延迟多由大事务、单线程回放导致GTID 提供全局事务 ID简化主从切换自动定位同步位点。十、MySQL 慢查询优化实战面试重点如何发现慢 SQL → 定位原因 → 优化手段结合 Explain 执行计划。一、慢查询基础(1)慢查询日志 slow_query_log开启后执行时间超过阈值long_query_time的 SQL 会记录到日志。long_query_time默认 10 秒生产一般设置 0.5~1 秒。log_queries_not_using_indexes记录没有使用索引的 SQL排查漏建索引。注意慢日志会有少量性能损耗线上可按需开启或用 pt-query-digest 分析。(2)其他抓慢 SQL 手段show processlist实时查看当前正在执行 SQL看长时间 running 的会话。performance_schema数据库内置性能监控采集 SQL 执行信息。第三方工具pt-query-digestpercona 工具集聚合分析慢日志。二、Explain 执行计划分析核心执行explain SQL重点看这几个字段(1)type访问类型优先级最高 性能排序system const eq_ref ref range index ALLref普通索引等值查询推荐range范围查询 between in可接受ALL全表扫描必须优化(2)key实际用到的索引NULL 代表没走索引。(3)rows预估扫描行数数值越大越慢。目标尽量让 rows 越小。(4)Extra额外信息高频标识Using index覆盖索引优秀无需回表Using filesort文件排序严重问题无法利用索引排序需要额外内存 / 磁盘排序Using temporary创建临时表常见 group by性能差三、慢 SQL 常见原因背诵没建索引触发全表扫描 ALL索引失效函数运算、隐式转换、like 左模糊、or、破坏最左前缀大事务单次事务处理海量数据锁等待、binlog 暴涨主从延迟索引过多写入insert/update/delete维护索引开销大查询返回大量数据select *一次性查出几十万行网络 内存压力join 多表关联关联字段无索引order by、group by 字段无索引触发 Using filesort / Using temporary锁等待行锁被其他事务持有SQL 阻塞执行时间拉长四、优化方案实战方案(1)索引优化禁止 select *只查需要字段尽量走覆盖索引避免回表联合索引遵循最左前缀等值条件放前面范围放后面避免索引列做函数、计算where substr(name,1,3)abc不走索引避免隐式类型转换where id123id 是数字字符串常量触发转换索引失效like 只允许xxx%禁止%xxx左模糊。必须模糊检索可用全文索引。(2)SQL 写法优化1.分页优化limit offset,sizeoffset 很大时越查越慢-- 低效 select * from table limit 100000,20; -- 优化主键过滤 select * from table where id100000 limit 20;2.in 列表中的值不宜过多建议控制在 1000 以内当集合较大时尽量将 in 改写为 join。3.尽量避免使用 not in、! 等写法否则会导致索引失效。4.减少子查询的使用优先采用 join 关联join 的关联字段必须建立索引并遵循小表驱动大表的原则。5.拆分大 SQL避免一次性查询海量数据。(3)业务层面优化大事务拆小不要一次更新几万条数据减少锁持有时间降低主从延迟冷热数据分离历史数据归档单表数据量过大做分库分表读多写少场景引入 Redis 缓存减轻 DB 压力读写分离读请求走从库注意主从延迟问题(4)参数层面优化innodb_buffer_pool_size缓存热点数据页服务器内存 50%~70%sort_buffer_size、join_buffer_size单会话缓冲区不要调太大容易内存暴涨innodb_flush_log_at_trx_commit根据业务安全要求权衡性能五、锁等待类慢 SQL 排查思路SQL 本身执行很快但是等待锁耗时很长show engine innodb status; 查看事务、锁等待信息找到持有锁的长事务kill 会话缩短事务执行时间事务内不要放外部接口调用高频深挖面试题Q1limit 大偏移量为什么慢数据库要扫描并丢弃前面 offset 条记录才返回后面数据。用主键 ID 过滤优化。Q2Using filesort 一定是磁盘排序吗不一定。优先在内存排序内存不够才落地磁盘无论内存还是磁盘都代表没有索引排序需要优化。Q3为什么不建议 select * ?1.读取多余字段IO 增加2. 无法触发覆盖索引发生回表3. 网络传输量大。Q4索引建的越多越好么不是。查询变快写入变慢。每次 insert/update/delete 都要维护 B 树索引索引越多写入压力越大。Q5大 in 怎么优化in 数量少直接用数量很大拆分成批量查询或者改成 inner join。一句话背诵总结慢查询通过慢日志、processlist 捕获Explain 重点看 type、rows、Extra慢 SQL根源缺少索引、索引失效、大事务、大分页、join 无索引优化优先改写 SQL 合理建索引避免 select *利用覆盖索引超大表冷热分离引入缓存分担压力锁等待类慢 SQL缩短事务时长。十一、分库分表原理与痛点适用场景单表数据量千万级以上查询、写入性能下降单库 CPU/IO 达到瓶颈。核心分为垂直拆分、水平拆分。一、两种拆分方式(1)垂直拆分纵向分库按业务模块拆库。例如订单库、用户库、商品库把不同业务表拆分到不同数据库实例。分表一张大表按字段拆成多张表。如 user 表拆 user 基础表id,name,phone、user_ext 扩展表id,remark,avatar。特点表结构不一样解决单表字段过多、大字段text拖慢查询问题。缺点跨表 join 变成跨库 join性能差。(2)水平拆分横向面试重点表结构不变按数据行拆分分到多个库 / 多张表。 常见分片策略1.取模分片shard id % N。id 对分表数量取模路由到对应表。✅优点数据分布均匀❌缺点扩容困难扩容需要迁移大量数据。2.范围分片按 id 区间、时间区间拆分。如 0~100w 在 t_order_0100w~200w 在 t_order_1。✅优点扩容简单❌缺点热点问题新数据全部落在最后一张表。3.一致性哈希对分片 key 做 hash 映射到哈希环新增节点只迁移部分数据。分片 key 选择一般选业务主键如 orderId尽量避免跨分片查询。二、中间件分类了解1.客户端分片Sharding-JDBC。jar 包形式应用层做 SQL 解析路由无独立代理。2.服务端代理分片MyCat。独立中间件数据库代理应用连接 mycat由代理路由。三、核心难点 痛点⭐高频考点(1)跨分片 Join 问题拆分后数据分布在不同库原生无法直接 join。 解决方案业务层 Join先查 A 分片拿到 ID 集合批量查 B 分片内存组装。冗余字段宽表提前冗余关联字段消除 join。全局表字典表地区、分类在所有分片都保存一份。(2)分布式 ID必考分表后不能依赖数据库自增 ID多个表自增会重复。 方案雪花算法 Snowflake64bit时间戳 机器号 序列号本地生成高性能。缺点依赖系统时钟时钟回拨会重复。数据库号段模式预分配一段 ID用完再取下一段。Redis 自增生成 ID。(3)分布式事务跨库操作本地事务失效。 方案最终一致性TCC、SAGA、本地消息表、事务消息RocketMQ强一致性XA 2PC性能差生产极少用。业务优先尽量设计成单分片事务规避分布式事务。(4)分页、排序、聚合order by / limit跨分片每个分片单独查询应用内存汇总再排序分页。 大 limit 分页性能极差。 优化带上分片 key 查询避免深度分页时间 / ID 条件过滤减少汇总数据。(5)扩容迁移问题取模分片最大痛点节点增加取模结果变化大量数据需要搬迁。 方案双写迁移旧分片继续写入同步迁移数据数据对齐后切换路由灰度上线。预分片预留足够分片数。(6)全局唯一约束单库唯一索引失效。例如手机号唯一数据分布多个分片数据库无法全局校验。解决通过 Redis / 分布式锁做唯一性校验。四、分库分表落地原则背诵能不分就不分。优先索引优化、读写分离、冷热归档。千万以下不轻易拆分。分片 key 慎重选择尽量让同一业务数据落在同一个分片减少跨分片查询。避免跨库事务、跨库 join。预估未来数据量提前规划分片数量减少后续扩容成本。高频深挖面试题Q1垂直拆分和水平拆分区别垂直按业务 / 字段拆分表结构不同水平按行拆分表结构相同。Q2雪花算法时钟回拨怎么解决记录上一次生成 ID 的时间戳如果当前时间小于上次时间等待时钟追上或抛出异常。Q3分片 key 为什么很重要查询不带分片 key会触发全分片广播查询性能暴跌。Q4分库分表和读写分离区别读写分离同一套数据主写从读解决读压力。 分库分表数据切割到多个库解决单库容量、读写瓶颈。两者可以一起使用。Q5什么场景不适合分库分表查询条件不固定大量不带分片 key 的查询大量跨分片 join业务简单数据量不大。一句话背诵总结分库分表分为垂直业务 / 字段、水平数据行拆分分片策略有取模、范围、一致性 hash痛点集中在跨分片 join、分布式 ID、分布式事务、分页排序、数据扩容迁移、全局唯一约束落地原则优先优化索引、读写分离尽量避免跨分片操作能不分则不分。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑