【问题标题】:Best modeling for Counting on a one to many relationship query计数一对多关系查询的最佳建模
【发布时间】:2016-11-19 07:54:20
【问题描述】:

我需要帮助来选择建模解决方案。

我有一个表 A,其记录与表 B 中的许多其他记录相关。例如:文本 (A) 和收藏它的用户 (B) 或产品 (A) x 评论 (B)。

所以...我想知道有多少人收藏了某个文本或评论了某个产品。好的,当这种情况只有一个查询时,这很容易,但是当我开始加入越来越多的表时会变得复杂。例如,查找喜欢或平均评论的用户名 + 评论中包含的照片 + 完全没有评论的产品,以及当有评论相关但仍因审核而被屏蔽时,等等。

我知道,仍然可以查询,但是...

如果表 A 有一列仅用于计算表 B 中相关的记录数,这是一个更好的解决方案吗?比如 Favorite_Count、review_count、review_avg、...

这将在一个复杂的查询中“保存一个连接”,以换取在某人喜欢或不喜欢某物时多一点编码。最后,查询会更容易阅读并且可能更快,对吧?

你怎么看?

【问题讨论】:

  • 我避免以这种方式将聚合数据存储在表中。如果您的应用程序行为不端,有人会说,嘿,这些数字不匹配,那么您将需要一个流程来确保它们匹配,接下来您将管理聚合器运行的频率以纠正错误的应用程序写入,与此同时,正在在线购买其他应用程序,它们会为您的聚合带来一系列问题。 GROUP BY 和 INNER JOINS 是您的朋友。也许您可以研究一个只读数据库,报告可以在那里运行并展平您的数据。
  • 我明白了卡米尔的观点,在阅读量非常大的情况下,我可以理解将更新信息管理到您的基本表中的复杂性,但我会支持罗斯,通常这是一个不必要的复杂情况只是为了另一个失败点。此外,如果您想要详细数据和聚合技术,例如分区窗口函数和具有适当索引的 CROSS APPLY 和优化,即使在高需求场景中也可以保持快速读取
  • 是的,我有点同意你的看法。但由于系统不会从 API 或其他地方获取外部输入,因此不太可能出现更新错误。但无论如何,这是一个很好的观点。但是看看现实世界的例子。这就是我正在尝试做的事情,这很困难:stackoverflow.com/questions/40346096/… 我必须考虑被屏蔽和隐藏的评论以及没有评论的产品,除了计算之外,还要对评论进行平均(只有那些没有被屏蔽和隐藏的评论)。因为我不是 SQL 专家,所以这对我来说很难。 :(
  • 我可以为 product_id 提供一个 update_count 函数(或存储过程)。每个更新操作都会触发该 product_id 的函数。

标签: sql sql-server database-design sqlperformance


【解决方案1】:

数据检索会更快。数据插入和更新会更慢。这是一个权衡。这取决于读写比率。

调查一下 StackOverflow 是如何做到这一点的,这对您来说非常有价值。您可以检查数据库架构here

例如,他们将AnswerCountTags 放在Posts 表中,即使每次都可以通过分别与Posts(分层结构)和PostTags 的附加连接轻松检索它们。

在我看来,他们之所以这样做,是因为此信息的阅读频率高于更新频率。想象一下有多少用户浏览了帖子列表,以及有多少人实际点击了每个帖子。要在主页上构建帖子列表,每次有人刷新它时都需要额外的时间来执行这些连接。那将是显着的流量,不是吗?

但话又说回来,这一切都取决于您的情况。在这种情况下没有“最佳方法”。

【讨论】:

  • 是的。这里也是一样的情况。额外的代码将在更新中完成。当版主阻止/取消阻止/删除评论时。但评分将适用于每一个产品,也适用于一个大的、分页的产品列表。收藏更容易一些...收藏或不收藏将触发该功能。
【解决方案2】:

我对这个问题的索引视图有很好的经验。这些非常适合计数计算。与“普通”视图相比,记录作为索引存储在 Sql-Server 中,并在相关表发生更改时自动更新。但是,这些有一些限制,例如模式绑定是强制性的,您只能使用内部连接,...。我会创建多个索引视图,然后查询它们。有关详细信息,请参阅 MSDN Create Indexed Views

CREATE VIEW dbo.v_productReviewsCount
  WITH SCHEMABINDING
AS
  SELECT T1.productId,
         COUNT_BIG(*) AS [count]
    FROM [dbo].[products] T1
         INNER JOIN [dbo].[reviews] T2
                 ON T1.productId = T2.productId
   GROUP BY T1.productId

GO

CREATE UNIQUE CLUSTERED INDEX ix_productReviewsCount_productId ON dbo.v_productReviewsCount (productId) 

GO

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多