【问题标题】:Surrogate Key vs Natural Key for EFEF 的代理键与自然键
【发布时间】:2013-12-01 21:34:43
【问题描述】:

我和我的同事正在尝试确定哪种方法是为两个数据库表设计架构和键的更好方法。一个是很少更改的查找表。它有大约 700 行。另一个表引用查找表。随着时间的推移,该表将有数千行。在设计 B 中,查找表有一个由 3 个 varchar 组成的主键。另一个表的主键由相同的 3 个 varchars 和两个日期字段组成。在设计 A 中,3 个 varchar 被替换为代理键。这 3 个 varchar 对它们有一个唯一约束 (UC)。

哪个设计更好?我的同事说,如果我们有一个代理键,当我们需要向用户显示数据时,在表上进行连接会变得非常慢。此外,拥有仅用于使行唯一的键是浪费的。我的论点是连接速度很快,并且为 3 个 varchar 存储额外数据是浪费的,因为它将这些数据复制到两个表中。

我们在 T-SQL Server 2008 中使用 EF 5 的 WPF 桌面应用程序中使用它。代理键还是自然键?附图显示了两种不同的设计。

【问题讨论】:

  • 马上,A 将比 B 更高效,因为您将加入单个 int 与 3 nvarchars。您可能仍希望为 3 列包含一个复合唯一键并包含一个代理键。
  • @FreshPrinceOfSO 我不同意。 “表演者”不是一个词。
  • @ypercube I found something that agrees with me 在互联网上。
  • 我确实在 3 列上包含了唯一约束。它只是没有显示在图表中。另外,我认为Performant是一个词。重构也是一个词(我最喜欢的词之一)。

标签: sql entity-framework tsql database-design


【解决方案1】:

表上只有几千行,我认为您不会注意到任何差异。即使一个表有数百万行,另一个也只有 700 行。SQL-Server 的设计目的是有效地进行连接,所以当你的同事声称连接到一个相当小的(700 行)表会影响效率。

设计 A 优于 B 的一个方面是更大的表 (PriceIndex) 会更窄,因此用于连接的索引也是如此。 4 个字节而不是 90 个字节可以大大提高性能。在设计 A 中,您可能需要的所有其他包含代理键的复合索引也将比在 B 中更窄。

设计 B 比 A 更有效的情况是涉及两个表中的 GROUP BY 列的查询。例如,如果您有一个带有GROUP BY Price, HubCode 的查询,则在设计 B 中,您可以在这 2 列上添加复合索引,而在设计 A 中,这些列将位于单独的表中,并且您不能使用来自 2 个表的列的索引。

另一个方面是是否有其他表以这些列作为主键,例如,如果您有另一个以(HubCode) 作为主键的表,另一个以(HubCode, TimeFrame) 和另一个以(IndexCode, HubCode) 的表,也许另一个以(IndexCode, HubCode, TimeFrame, StartDate, EndDate, CustomerID) .使用设计 B(所有表都具有自然键),涉及来自多个表的连接的几个复杂查询可以更有效,因为可以消除一些中间连接。使用设计 A(代理键),不能跳过中间连接,并且当(中间)表很大时,查找成本会变得非常大。

最后,没有什么比测试您的数据和您希望表增长的大小以及您希望运行的查询类型更重要的了。

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 2012-09-26
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    相关资源
    最近更新 更多