分库分表,比如我们有一个外卖订单表,里面有用户id,商家id,如何分表
我们继需要根据用户id查询,也需要根据商家id来查询,如何实现?
通过索引表
🏗️ 三、业界标准做法:主表分片 + 商家索引表 📌 作用:
- 存储商家维度到订单ID的映射;
- 商家查订单时,先查索引表拿到 order_id 列表;
- 再根据
order_id(解析分片信息)精确查询主表。
1️⃣ 生成带分片信息的 orderId(嵌入 user_id hash) 2️⃣ 写入主表(按 user_id 分片) 3️⃣ 写入商家索引表(按 merchant_id 分片)
| 项 | 优点 | 缺点 |
|---|---|---|
| ✅ 用户查询 | 单分片命中,高效 | 无 |
| ✅ 通过 orderId 查询 | 可直接定位分片 | 无 |
| ✅ 商家查询 | 可通过索引表 + orderId 精准查 | 多一次查询跳转 |
| ⚠️ 一致性 | 需保证主表与索引表同步 | 需异步补偿机制 |
exist和in
- EXISTS 不依赖子查询的结果集大小,IN 会有性能劣化 IN 会先把子查询的结果 全部查出来、构造成列表(可能很大)
EXISTS 是 逐行判断是否存在匹配记录,子查询只要匹配到 1 条就立即返回,不需要扫描全部。
- IN 列表是小的常量列表 什么时候一定用 EXISTS?
✔ 子查询数据量大(10万 - 上千万)
✔ 子查询字段有索引
✔ 子查询可能出现 NULL
✔ 不希望生成大量临时表
✔ 希望利用 MySQL 半连接优化(semi-join)
线上发生了Tomcat假死(进程还在),你觉得有哪些可能性?怎么排查
千万级大表如何添加字段,变更
在低版本的 MySQL 中,千万级数据量的表中添加字段时,直接使⽤ 致⻓时间锁表、甚⾄数据库崩溃等 可以使⽤ Percona Toolkit 的 pt-online-schema-change 来完成,它通过创建临时表、逐步同 步数据并使⽤触发器捕获变更来实现
redo log
刷盘时间
- 0 表示事务提交的时候不刷盘,后台线程1s执行一次。
- 1 事务提交的时候,立即刷盘。 最安全,默认
- 2 写入pageCache,🈶操作系统来确认。
LinkedBlockingQueue和ArrayBlockingQueue的区别?
都是阻塞队列。一个是基于数组,一个基于链表,默认是Inter.MXA_value, 一个是基于ReentrantLock,另一个是基于2个锁来实现的。
你能说下在日常编码过程中怎么防止死锁,从写代码的角度(获取锁时增加超时时间,然后按照资源排序获取锁)
一个事务里面有两条sql,一条sql冲突高、一条sql冲突低,你觉得把哪条sql放前面执行性能好
InnoDB 中:
- 行锁在 事务提交(COMMIT)时 统一释放;
- 所以越早加锁 → 持锁越久 → 越容易引起锁等待。
mysql可重复读和读已提交加的行锁有什么区别?
| 特性 | READ COMMITTED | REPEATABLE READ(默认) |
|---|
| 读取版本 | 每次读取最新提交版本 | 事务开始时的快照(MVCC) |
|---|
| SELECT … FOR UPDATE | 只锁当前行 | 锁当前行 + 间隙锁(Next-Key Lock) |
|---|
| 防止幻读 | ❌ 可能出现幻读 | ✅ 幻读被间隙锁阻止 |
|---|
| 不可重复读 | 可能发生 | ✅ 避免(事务快照一致) |
|---|
| 插入新行 | 可能插入到锁范围内 | 被间隙锁阻止,无法插入到锁范围内 |
|---|
8、mysql可重复读和读已提交加的行锁有什么区别?
19、唯一索引和主键索引加的锁有什么区别?
MVCC
全程是多版本并发控制,是一种并发控制机制,解决数据库中多个事务同时读写同一行数据的冲突问题,实现读和写操不互斥。通过保存数据的多个版本,让读操作读到的是符合自己视角的数据版本,而不需要加锁。
- 读写并发冲突。(解决)
- 不可重复读(解决)
- 幻读
redis
sentinmal主观下线。客观下线
redis如何实现延迟队列
一、使用 Sorted Set(ZSET)实现延迟队列
member是任务的id,score是任务执行的时间戳,后台线程定时扫描,如果任务到期,就执行。执行后,删除掉任务。
Mysql的主从有哪几种同步方式
异步: 主库写完binglo,就提交事务,不等从库。
半同步: 主库写完binlog,等待至少一个从库确认接受后,才提交。
全同步:
等所有的从库确认后。
2. 跳跃表的查找、插入和删除操作
-
查找操作 从最高层索引的头节点开始,
- 如果当前节点的下一个节点的值小于要查找的值,则向右移动;
- 如果当前节点的下一个节点的值大于要查找的值,则向下移动,
- 直到找到目标值或者确定目标值不存在。
-
插入操作 首先进行查找操作,找到插入位置。然后随机生成一个层数,根据这个层数在每一层插入新节点。
-
删除操作: 首先进行查找操作,找到要删除的节点。然后在每一层删除这个节点。
3. 跳跃表的时间复杂度分析
由于跳跃表的层级结构,查找、插入和删除操作的平均时间复杂度和最坏时间复杂度都是O(log n),其中n是跳跃表中元素的数量。这使得跳跃表在处理大量数据时具有很高的效率。同时,跳跃表的空间复杂度是O(n),因为每个元素都需要存储在跳跃表中