【问题标题】:SQL queries - try to avoid dulicate data in result set?SQL 查询 - 尽量避免结果集中的重复数据?
【发布时间】:2012-01-14 12:26:49
【问题描述】:

这是一个我想了很久的问题。我会尝试通过一个例子来解释,但这是一个普遍的问题。

假设你有两张桌子:

  1. users,保存用户的名字、姓氏……
  2. posts,保存用户撰写的帖子,包含标题、文本、...等字段。

现在,假设我想显示过去 24 小时内创建的所有帖子。在此表中,我想显示创建此帖子的用户的名字、姓氏……。查询可能类似于:

SELECT ... FROM posts, users WHERE posts.user_id = users.id AND [last 24 hours]

现在,我的问题。由于一个用户很可能在过去 24 小时内创建了多个帖子,因此我们基本上是在一次又一次地检索他/她的名字、姓氏……。也就是说,上述查询的结果集包含重复数据(但不包含重复行)。

这样做不是更好吗:

  1. SELECT ... FROM Posts WHERE [过去 24 小时]
  2. SELECT ... FROM users where id IN(SELECT DISTINCT user_id FROM posts WHERE [last 24 hours])
  3. 在应用程序级别或 sql 过程中将第一个查询的结果与第二个查询的结果映射,以找出帖子的名字、姓氏…… - 如果标识符(主键) 是某种哈希映射、数组或类似的索引/键。

?

我知道这是一个非常笼统的问题,但欢迎提供任何见解。谢谢!

【问题讨论】:

  • 在你的上下文中更好的意思是什么?

标签: sql duplicates duplicate-data duplicate-removal


【解决方案1】:

任何一种方法都应该有效,但你找到了重要的部分:

在应用程序级别进行。

对我来说,我会提取重复数据,以便结果集中的每一行都包含我需要的所有数据。 SQL 在JOINs 和 set 操作上比几乎任何声明性语言都更有效。

如果您将数据保存在一起,您将更容易在需要时将其分解到下游,并且您只需调用一次数据库而不是两次。

随着重复数据的增长,这样做的好处会减少。如果只是几个领域,影响不大。如果是几十个冗余数据字段,性能差异会更加明显。

对于您的具体示例,最好在一个查询中完成所有操作。

如果您感到困扰,您可以在应用程序级别消除重复,但与进行多次数据库调用相比,为同一用户多次返回 2 或 3 个额外字段不会很重要。

【讨论】:

    【解决方案2】:

    最佳解决方案取决于每个表中的行数,以及每个用户每天的帖子数。

    如果帖子相对较少,用户较多,那么一次选择帖子和用户即可。

    如果用户很少,每个用户的帖子很多,最好使用第二个选项,分别选择它们。首先,您将选择过去 24 小时内的帖子,然后您将选择这样的作者:

    SELECT users.id, first_name, last_name
    FROM users
    LEFT JOIN posts ON users.id = user_id
    WHERE [posts in the last 24 h]
    

    【讨论】:

      【解决方案3】:

      我认为最好的解决方案可能是选择用户,即最近 24 小时有消息,然后按用户 ID 选择消息。

      1. step:
      
      SELECT DISTINCT id, first_name, last_name
      FROM users INNER JOIN
      posts ON posts.user_id = users.id
      WHERE [last 24 hours]
      
      2. step:
      
      SELECT *
      FROM posts
      WHERE user_id = @userId AND [last 24 hours]
      

      这种方式会导致更多的数据库调用但更少的内存使用,因为您一次只为 1 个用户检索消息。

      【讨论】:

      • 您认为运行几十个查询会更好吗?他可能有很多用户在过去 24 小时内发过帖子。
      • 您认为最好将所有消息和用户详细信息的数据读取到内存中,大量消息在哪里?
      • 是的。在这种情况下,我们谈论的是每行额外的 20-30 个字节。其影响将远小于进行数百次数据库调用。
      • 一切看环境,具体用在企业内网,连接速度很快,与数据库调用次数无关。
      猜你喜欢
      • 2014-04-24
      • 1970-01-01
      • 2018-05-03
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多