【问题标题】:Maintaining a metadata table in SQL在 SQL 中维护元数据表
【发布时间】:2009-12-23 00:56:33
【问题描述】:

有人可以帮助我解决这样的情况吗? 一个包含所有用户信息的用户表,用户ID是用户表的主键。我有另一个表,例如 Comments,它包含任何用户创建的所有 cmets。 Comments 表包含 UserID 作为外键。现在我必须根据用户添加的 cmets 数量对用户进行排名。用户添加的 cmets 越多,排名就会上升。我想看看什么是最好的方法来做到这一点。

我希望有另一个表,它基本上包含用户的所有属性或统计信息(将来可能会有更多属性,现在只有排名,基于评论数),而不是在用户表本身中添加另一列.

如果我创建另一个名为 UserStats 的表,并将 UserID 作为外键,并有另一个名为 Rank 的列,则每次用户添加评论时,我们可能需要更新排名。我如何编写一个执行此操作的 SP,我什至不确定这是否是正确的方法。

【问题讨论】:

    标签: sql sql-server stored-procedures


    【解决方案1】:

    这不是正确的做法。

    在出现性能问题之前,您不希望将这些类型的计算值具体化 - 在您开始执行建议的操作之前,您可以使用诸如索引视图之类的选项来帮助您。

    只需创建一个名为 UserRankings 的视图并让它看起来像:

    SELECT c.UserId, COUNT(c.CommentId) [Ranking]
    FROM Comments c
    GROUP BY c.UserId
    

    不确定您想如何进行排名,但您也可以查看 T-SQL 中的 RANK() 和 DENSE_RANK() 函数:Ranking Functions (Transact-SQL)

    【讨论】:

      【解决方案2】:

      你可以通过查询来做到这一点

      SELECT UserID,
         COUNT(UserID) CntOfUserID
      FROM UserComments
      GROUP BY UserID
      ORDER BY COUNT(UserID) DESC
      

      您也可以使用 ROW_NUMBER 执行此操作

      DECLARE @Comments TABLE(
              UserID INT,
              Comment VARCHAR(MAX)
      )
      
      INSERT INTO @Comments SELECT 3, 'Foo'
      INSERT INTO @Comments SELECT 3, 'Bar'
      INSERT INTO @Comments SELECT 3, 'Tada'
      
      INSERT INTO @Comments SELECT 2, 'T'
      INSERT INTO @Comments SELECT 2, 'G'
      
      
      SELECT  UserID,
              ROW_NUMBER() OVER (ORDER BY COUNT(UserID) DESC) ID
      FROM    @Comments
      GROUP BY UserID
      

      【讨论】:

        【解决方案3】:

        存储这类信息实际上是个坏主意。每个用户的 cmets 计数可以在任何给定时间快速轻松地计算出来。如果你的列被正确索引(在外键上),计数操作应该很快发生。

        您可能希望保留元数据的唯一原因是,如果您的数据库上的负载快速而剧烈,并且您根本无法承受每个请求的计数运行选择查询。并且该负载还将告知您是简单地将列添加到用户表还是创建一个完整的单独表。 (后一种解决方案适用于最极端的服务器负载。)

        【讨论】:

          【解决方案4】:

          几个cmets:

          是的,我认为您应该将“分数”元数据保存在某个地方,否则,您必须每次都运行评分计算,这最终会变得很昂贵。

          其次,我认为您不应该计算实际的“排名”(相对于其他用户)。只需计算一个“分数”(基于发布的 cmets 的数量),然后您的查询可以通过按降序检索分数来确定“排名”。

          第三,我可能会创建一个触发器,根据对 cme​​ts 表的每次插入来更新元数据表中的“分数”。

          【讨论】:

          • 物化计算数据和使用触发器是不能轻易完成的事情。我不认为这些计算像你想象的那么昂贵,而且这些东西可以很容易地在表示层缓存一段时间。
          猜你喜欢
          • 1970-01-01
          • 2014-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-30
          • 2016-07-16
          • 2010-10-18
          相关资源
          最近更新 更多