20多个表,每个都有userId 和其他几个属性,要根据userId把他们全部汇总,如何处理?

20多个表,每个表都有userId 和几个属性,要把他们全部都拼到一张表,怎么处理?

按 userId 汇总关联 20 张表。

面对 20多张表 的全量字段合并(宽表化),这是一个 ETL(抽取、转换、加载) 过程。

如果直接用 JOIN 拼 20 张表,上百万行数据在执行时会产生巨大的笛卡尔积风险,且极易触发 MySQL 的溢出或者超时。

方案一:SQL 离线宽表化(推荐)

采用 "主表 + 逐步左连接" 的方式,分步写入一张中间宽表。

1. 创建目标宽表(大宽表)

先创建一个包含所有字段的宽表。

注意:关联字段必须全部建有索引。

这 20 张表参与关联的 user_id 必须全部建有索引。

sql 复制代码
CREATE TABLE tmp_user_profile_20260414 AS 
SELECT user_id FROM tmp_data_20260414;

ALTER TABLE tmp_user_profile_20260414 ADD PRIMARY KEY (user_id);
2. 分步更新(分而治之)

每张表单独更新到宽表中,这样即使某张表数据有问题,也不会影响整体流程。

使用 sql 的 Update Join 处理。

sql 复制代码
-- 拼入数据
UPDATE tmp_user_profile_20260414 w
JOIN (SELECT user_id, AVG(diff) as avg_sleep FROM t_sleep GROUP BY user_id) s 
  ON w.user_id = s.user_id
SET w.avg_sleep_seconds = s.avg_sleep;

-- 重复上述步骤,直到 20 张表全部拼完

方案二:Java 内存并行映射(高性能,适合逻辑复杂)

如果某些表的属性需要复杂的 Java 逻辑计算,建议在后端处理:

  1. 定义 Map 容器:Map<Long, UserProfileDTO> profileMap
  2. 并行查询:使用 CompletableFuture 并行开启 20 个任务,每个任务查一张表并按 user_id 塞入 Map。
  3. 批量写入:拼装完成后,利用 MyBatis 的 batchInsert 一次性落库。
相关推荐
nanxun8861 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103511 天前
Day01 | Java 基础(Java SE)
java
行者全栈架构师1 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师2 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_02 天前
mac(m5)平台编译openjdk
java
唐青枫3 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
云技纵横3 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
沉默王二3 天前
面试官:RAG 不用向量数据库,用 MySQL 硬扛?我:100 万向量不是很轻松?
mysql·面试·ai编程
一个做软件开发的牛马3 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261353 天前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java