这个问题我想了很久。我将尝试通过示例进行解释,但这是一个一般性问题。
假设您有两个表:
- users,包含用户的名字、姓氏……
- posts,包含用户撰写的帖子,包含标题、文本、...等字段
现在,假设我想显示过去 24 小时内创建的所有帖子。在此表中,我想显示创建此帖子的用户的名字、姓氏……。查询可能类似于:
SELECT ... FROM posts, users WHERE posts.user_id = users.id AND [过去 24 小时]
现在,回到我的问题。由于一个用户很可能在过去 24 小时内创建了多个帖子,我们基本上是一遍又一遍地检索他/她的名字、姓氏……。换句话说,上述查询的结果集包含重复数据(但不是重复行)。
这样不是更好吗:
- SELECT ... FROM posts WHERE [过去 24 小时]
- SELECT ... FROM users where id IN (SELECT DISTINCT user_id FROM posts WHERE [last 24 hours])
- 在应用程序级别或在 sql 过程中将第一个查询的结果与第二个查询的结果进行映射,以找出帖子的名字、姓氏……——如果标识符(主键),这很容易完成) 是某种 HashMap 、数组或类似的索引/键。
?
我知道这是一个非常笼统的问题,但欢迎任何见解。谢谢!
最佳答案
这两种方法都应该可行,但您捕获了重要的部分:
在应用层做。
对我来说,我会提取重复数据,以便结果集中的每一行都包含我需要的所有数据。 SQL 在 JOIN
和集合操作方面比几乎任何声明性语言都更高效。
如果您将数据放在一起,您将更容易在需要时将其分解到下游,而且您只需调用一次数据库而不是两次。
随着重复数据的增长,这样做的好处会逐渐减少。如果只是几个领域,那影响不大。如果是几十个字段的冗余数据,性能差异会更加明显。
对于您的具体示例,最好在单个查询中完成所有操作。
如果您感到困扰,您可以在应用程序级别消除重复,但是与进行多次数据库调用相比,为同一用户多次返回 2 或 3 个额外的字段不会非常重要。
关于SQL 查询 - 尽量避免结果集中的重复数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8862191/