From 000c0d8ef36d8496219811cdf2073e32615630a8 Mon Sep 17 00:00:00 2001 From: piaofeng <574073703@qq.com> Date: Sat, 22 Feb 2025 15:05:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=AF=8F=E5=91=A8=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 202502-04-weekly.md | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 202502-04-weekly.md diff --git a/202502-04-weekly.md b/202502-04-weekly.md new file mode 100644 index 0000000..b5b7b18 --- /dev/null +++ b/202502-04-weekly.md @@ -0,0 +1,77 @@ +# 一、Cool Share + +# 二、Weekly Challenge + +一个技术债务的优化。 + +* 业务背景 + +社区业务,用户可以发帖,发帖的时候可以带话题。 +> 话题有两种,一种是系统预设好的,用户发帖只能用这一些, +> 另外一种是支持用户自定义输入,目前假设只有第一种。 + +topic 话题表和 status 表的设计假设如下: +```sql +REATE TABLE topic ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键 id', + topic_name VARCHAR(255) NOT NULL COMMENT '话题名称' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='话题表'; + +REATE TABLE status ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键 id', + content VARCHAR(500) NOT NULL COMMENT '帖子内容', + topics VARCHAR(200) COMMENT '帖子话题' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='话题信息表'; +``` +* 业务痛点 + +周一上班,DBA 发来一个工单,说你这个模块慢 SQL 了。 +```sql +select count(1) from status where topics in('DeepSeek', 'ChatGPT'); +select * from status where topics in('DeepSeek', 'ChatGPT'); +``` +开始找这条 sql 的业务入口,发现是:话题管理模块和话题帖子管理模块,列表段如下。 +```text +1、话题管理模块 +话题名称 话题 状态 帖子数量 + +2、话题帖子管理 +先查询到话题,然后拿到这个话题下的帖子数据做分页展示。 +``` + +去看一下发帖链路,发现在记录帖子数据的时候,直接把话题的 name 写入到了话题表的 topics 字段中了。 + +注意:这个是一个历史缺陷,有存量数据,怎么修复?考验一下工作方法、思路。 + +当前面那个修复方案有了之后,如果你来设计这个模块,如何考虑? + +# 三、解决思路 +考虑的点: +1、topic 表 topic_name 会修改过,那么 status 表的 topics 字段会存在历史记录,跟 topic 表关联不上 + +处理方式: +一、如果 topic 表的 topic_name 不会进行更改 +1、status 表的 topics 加上索引即可,会明显提升查询效率 + +2、如果 in 的取值范围很大,查询效率会受到影响,甚至退化成全表查询(跟 range_optimizer_max_mem_size 的配置值有关) + +二、如果 topic 表的 topic_name 会进行更改 +1、status 表添加 topic_id 记录 topic 表的 id,并且建立索引,topic_name 只是作为冗余值。 + +2、status 通过关联查询,补充上 topic_id 字段的值(需要考虑 topic_name 的历史值怎么关联 topic 表的 id) + +3、in 查询的字段修改为 topic_id,不再使用 topic_name + + +扩展思路 +1、根据 status 表的 topics 字段猜测,一个帖子是否会支持多个话题,status 表和 topic 表是一对多的关系 + +新增 status 和 topic 的一对多关联表 +```sql +CREATE TABLE status_to_topic ( + topic_id BIGINT NOT NULL COMMENT '话题 id', + status_id BIGINT NOT NULL COMMENT '帖子 id' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='帖子-话题关联表'; +``` + +2、topic_id 建立普通索引,status_id 建立唯一索引 \ No newline at end of file -- Gitee From 47bd2d9b2c774cbe28ec8809e8c10158da1be7fb Mon Sep 17 00:00:00 2001 From: piaofeng <574073703@qq.com> Date: Sat, 22 Feb 2025 07:09:57 +0000 Subject: [PATCH 2/2] update 202502-04-weekly.md. Signed-off-by: piaofeng <574073703@qq.com> --- 202502-04-weekly.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/202502-04-weekly.md b/202502-04-weekly.md index b5b7b18..ad7fcbb 100644 --- a/202502-04-weekly.md +++ b/202502-04-weekly.md @@ -46,16 +46,20 @@ select * from status where topics in('DeepSeek', 'ChatGPT'); 当前面那个修复方案有了之后,如果你来设计这个模块,如何考虑? # 三、解决思路 -考虑的点: +* 考虑的点: + 1、topic 表 topic_name 会修改过,那么 status 表的 topics 字段会存在历史记录,跟 topic 表关联不上 -处理方式: +* 处理方式: + 一、如果 topic 表的 topic_name 不会进行更改 + 1、status 表的 topics 加上索引即可,会明显提升查询效率 2、如果 in 的取值范围很大,查询效率会受到影响,甚至退化成全表查询(跟 range_optimizer_max_mem_size 的配置值有关) 二、如果 topic 表的 topic_name 会进行更改 + 1、status 表添加 topic_id 记录 topic 表的 id,并且建立索引,topic_name 只是作为冗余值。 2、status 通过关联查询,补充上 topic_id 字段的值(需要考虑 topic_name 的历史值怎么关联 topic 表的 id) @@ -63,7 +67,8 @@ select * from status where topics in('DeepSeek', 'ChatGPT'); 3、in 查询的字段修改为 topic_id,不再使用 topic_name -扩展思路 +* 扩展思路 + 1、根据 status 表的 topics 字段猜测,一个帖子是否会支持多个话题,status 表和 topic 表是一对多的关系 新增 status 和 topic 的一对多关联表 -- Gitee