【问题标题】:Redundant DB column for indexing用于索引的冗余 DB 列
【发布时间】:2014-04-01 22:11:29
【问题描述】:

我定义了几个数据库表,大致是这样的:

为了快速运行查询,其中按时间顺序检索 PersonMailMessages,无论 MailAccount 发送到什么,我想要一个 MailMessage 表的索引,按 (PersonId ,接收时间)。这意味着在 MailMessage 表中添加一个冗余的 PersonId 列,如下所示:

...或者是吗?有没有更简洁的方法来做到这一点?如果不是,最好将 PersonId 设为 MailMessage 表中的外键,还是不应该这样做,因为它在概念上不是外键,而只是用于 (PersonId, ReceivedTime) 索引的列?

【问题讨论】:

    标签: database database-design


    【解决方案1】:

    是的,您可以这样做,但它需要在{MailAccountId, PersonId} 上的表MailAccount 中有一个键,因此它可以被表MailMessage 中的FK 引用。从强制唯一性的角度来看,这是多余的,因为仅{MailAccountId} 就已经是唯一的了。

    还有另一种选择:使用识别关系和自然键。例如:

    这实现了基本相同的目标,但每个表只有一个键(和基础索引)。

    注意底部表格中PK字段的顺序:它允许查询...

    SELECT *
    FROM MailMessage
    WHERE PersonId = ?
    ORDER BY ReceivedTime
    

    ...通过对主索引的索引范围扫描来满足。如果表恰好是clustered,那么 DBMS 之后甚至不必访问表堆(根本没有表堆 - 行直接存储在 B-Tree 中)。

    在不使用冗余键的情况下避免 JOIN(这也有利于集群)是自然键与代理键的优点之一。可以想象,list of pros and cons 并没有就此结束。

    【讨论】:

      【解决方案2】:

      你正在做的事情叫做denormalization。对这个概念的优缺点进行全面讨论对 SO 来说有点过分。

      这种类型的优化也可以使用Materialized View(在 SQL Server 中称为索引视图)。

      【讨论】:

      • +1:有一个名字(非规范化)让它感觉更合法:-)。
      猜你喜欢
      • 2018-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      相关资源
      最近更新 更多