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 一次性落库。
相关推荐
xuhaoyu_cpp_java1 天前
MySql学习(二)
经验分享·笔记·学习·mysql
WiChP1 天前
【V0.1B6】从零开始的2D游戏引擎开发之路
java·log4j·游戏引擎
leaves falling1 天前
C/C++ 的内存管理,函数栈帧详讲
java·c语言·c++
文静小土豆1 天前
Java 应用上 K8s 全指南:从部署到治理的生产级实践
java·开发语言·kubernetes
神の愛1 天前
@Pattern,@NotBlank
数据库·mysql
zhimingwen1 天前
初探 Java 後端開發:解決 macOS 環境下 Spring Boot 項目啟動的各類「坑」
java·spring boot
Rsun045511 天前
3、Java 工厂方法模式从入门到实战
java·开发语言·工厂方法模式
Chasing__Dreams1 天前
Mysql--基础知识点--99--两个线程同时给同一个间隙加锁 造成死锁的原因
数据库·mysql
田梓燊1 天前
leetcode 142
android·java·leetcode
北有树1 天前
Mysql专题面试题总结
数据库·mysql