数据冗余 - 加入大型结果集

Posted

技术标签:

【中文标题】数据冗余 - 加入大型结果集【英文标题】:Data redundancy - JOIN with large result set 【发布时间】:2021-05-10 17:30:37 【问题描述】:

我遇到了数据冗余问题。我在 mysql 中的 JOIN 查询创建了一个非常大的数据集(~8mb),而很多数据是多余的。经过分析,我可以看到查询速度很快,但数据传输可能需要几秒钟。我有什么选择?

比如说我有两张表

用户:

user_id user_name
Alex
2 Joe

和购买:

user_id purchase_id purchase_amount
A  100
2 B  200
C  300
D  400

如果我只是 LEFT 加入表格

SELECT users.user_id, users.user_name, purchase_id, purchase_amount 
FROM Users 
LEFT JOIN purchases ON users.id = purchases.user_id

我会得到一个结果:

user_id user_name purchase_id purchase_amount
Alex A  100
2 Joe B  200
Alex C  300
Alex D  400

然而,正如我们所见,user_id 1 和 user_name Alex 存在于三个地方。对于非常大的结果集,这可能会成为一个问题。

我正在考虑使用 GROUP BY 和 GROUP_CONCAT 来减少冗余。这通常是个好主意吗?我的第一个测试似乎有效,但我必须设置 MySQL SET SESSION group_concat_max_len = 1000000;,这可能不是一件好事,因为我不知道将其设置为什么。

例如,我可以做类似的事情

SELECT user_id, user_name, GROUP_CONCAT(CONCAT(purchase_id, ':', purchase_amount)) 
FROM Users 
LEFT JOIN purchases ON users.id = purchases.user_id 
GROUP BY user_id, user_name

最终得到一个结果:

user_id user_name GROUP_CONCAT...
Alex A:100,C:300,D:400
2 Joe B:200

我还有其他选择吗?这是要走的路吗?解析连接的列不是问题。我正在尝试解决返回的大型数据集。

【问题讨论】:

您可以选择特定的列而不是users.*,以减少必须传输的冗余信息量。 我需要所有用户列,就像我在 concat/group 中所做的那样。 另一种选择是在应用程序中进行单独的查询。执行一次查询以获取所有users 信息,循环并执行单独查询以获取他们的购买。这通常被认为是糟糕的设计,但如果您描述的方法效果不佳,它可能是一个可以接受的替代方案。 @Barmar 我已经考虑过了。但这不是一种选择,因为这会导致成千上万的查询。您认为 GROUP_BY 方法有什么问题吗? 那么我认为您被问题中显示的两个选项所困扰。对于GROUP_CONCAT(),您可以进行第一次查询以获取连接的最大长度,然后将group_concat_max_len 设置为大于该长度。但这可能很昂贵。你可以从COUNT(*) GROUP BY user_id的最大值估计 【参考方案1】:
    我们之间可以有临时表吗? 使用 apache spark 的 map reduce 获取所需格式的数据。

【讨论】:

以上是关于数据冗余 - 加入大型结果集的主要内容,如果未能解决你的问题,请参考以下文章

imagenet100多大

Mongo dB 副本集冗余测试

数据集的概念mysql

Core Data/SQLite 是不是压缩冗余信息?

Linux 独立冗余磁盘阵列介绍

Leetcode之并查集专题-684. 冗余连接(Redundant Connection)