2010-08-19 89 views

回答

3

是,多列主键仍然是一个不错的选择,如果:

  • 主键也是聚集键
  • 您的表中还包含其他非群集指数

因为:

  • 来自聚类密钥(例如,单INT柱,或者复合键)将被添加到每个和每个每个条目和每一个非聚集索引

因此:如果有的在大小为200个字节的复合主键,你必须你桌子上的一些非聚集索引,你会在你的SQL Server上浪费很多的内存 - 而不仅仅是在(相对便宜的)磁盘上,而且在SQL Server主内存中(通常不是相当便宜)。

除了浪费空间之外,您的性能也会滞后,因为较大的索引意味着更多的磁盘I/O用于相同的操作。

一般来说:用你的桌子上只有复合主键,如果你从来没有需要引用表(真的从来没有,甚至在未来的),如果你有没有其他非聚集索引上那张桌子。

+0

你已经给出了一些原因,为什么不在SQL Server中有一个过大的聚集索引。但是,这些问题与主键无关。聚集索引和密钥不是同一个东西 - 即使在SQL Server中也是如此。另外,组合键可能比单个属性键小 - 因此单独的大小不是避免组合键的参数。 – sqlvogel 2010-08-19 09:36:08

+0

@dportas:严格来说,你是对的。但是,SQL服务器中至少有90%的主键也是集群密钥 - 主要是因为许多开发者根本不知道关于集群密钥的任何信息,并且主密钥自动成为集群密钥。 – 2010-08-19 10:48:22

+0

我有一个表的主要(集群)密钥是用户名和日志表的时间戳。我觉得这很好,因为它是桌上唯一的*索引/键。它可以快速为单个用户生成总和,因为UserID是该聚簇索引(主键)中的第一个*列,并且在索引中包含时间戳记可确保它是唯一的。这听起来不错吗? – Triynko 2013-04-10 17:31:08

0

业务需求(数据完整性要求)应该是决定实施哪些密钥的决定因素。在一个属性上强制执行唯一性显然与在多个执行上执行唯一性不同,因为在一种情况下允许的重复将不被允许在另一个上(除非您实现了两个键当然)。

请注意,marc的答案只适用于聚集索引,而不是主键。它们不是同一件事。他的回答也特定于SQL Server。

+0

是的,我的回答是SQL Server特有的,是的,它适用于集群密钥 - 但默认情况下,您的SQL Server主键** ARE **集群密钥 - 除非您明确禁用 - 可能绝大多数开发人员赢得't do ..... – 2010-08-19 10:49:34

+0

亲爱的ALL, 我对以上的所有答复感到困惑。 如果在我的情况下,复合键是主键,它也会有聚簇索引,这个表永远不会用作FK,并且没有其他非聚簇索引,那么wat会影响插入和更新。 这里有必要提到这张表会有大量的数据。 – ibrar 2010-08-19 10:52:22

+0

@图书馆:当然是有影响的。这种约束的目的正是为了防止不正确的更新或插入。显然,在执行此检查时会有开销,但如果您不想检查唯一性,那么您根本不会实现该约束。因此,是否在单列或多列上实现它不是一个与性能相关的问题 - 这取决于你想要达到的目标。我没有意识到索引中单列或多列之间的性能差异,但它可能取决于许多因素,所以我建议你自己测试一下。 – sqlvogel 2010-08-19 12:05:20

1

你怎么可能绝对肯定你的钥匙“永远不能被FK引用”?

您的属性组合确实是唯一的(否则您不会考虑将其作为“主键”)。

因此,您的属性组合是您的表中描述的真实世界事物的有效识别方法。

说这个永远不可能被FK引用,等于说“没有关于这种类型的东西的额外信息将永远与业务相关”。你怎么可能知道?

+0

亲爱的,感谢您的及时回复,但我仍然遵守我的声明“永远不会被FK引用”,因为特定的表格在我的数据库中表格的最小值是最低的。如果你需要,那么我会给你一个确切的例子在我的情况。 – ibrar 2010-08-19 10:43:19

+0

将其设计为永远不会被FK引用是非常容易的,因为通过设计某些类型的信息是独立的和最终的。例如,具有UserID复合群集主键,Timestamp的日志表是唯一的,并且首先与UserID群集,因此可以使用最少的I/O快速检索单个用户日志。其他表无需引用这样的日志条目/键的原因是因为它是由设计自包含的。换句话说,没有新的/外部/额外的信息需要在单独的表格中引用或添加到该行。 – Triynko 2013-04-10 17:45:18

0

在这个问题上有两个竞争的哲学。

我一直在使用复合主键来处理某些表格,我自己。

当我设计一个数据库时,我使用ER建模在一个地方收集信息需求。数据库提供的每个值都是一个属性的实例,每个属性都描述了一个主题实体或两个或更多主题实体之间的关系。外键不会进入分析阶段。

在开始数据库设计之前,我会从应用程序的角度决定如何识别每个实体。这些将给我我的主键。每个描述实体的表都有一个简单的主键,即实体的标识符。简单的关系(二进制,多对一)不需要自己的表。每个描述复杂关系的表都将有一个由参与实体的主键组成的复合主键。

外键以明显的方式插入。至少,对我来说很明显。这提供了3NF的初始表格设计,也许更高。表设计可能会通过进一步的规范化或其他与规范化不兼容的设计模式(所谓的非规范化)而改变。但这是桌子设计的第一次剪裁。

这种设计实践在性能和数据完整性方面产生了与普遍实践不同的结果。预调整练习在每个表的第一列中放置一个名为“id”的自动编号列。该列成为主键。

实际上,这种做法使用SQL表结构来模拟数据的图形模型,即使它看起来像关系模型。 id列实质上是该行地址的代理。数据的图形模型具有上升趋势和下降趋势。如果有需要,更多信息