是SQL Server中必需的主键吗?

这可能是一个相当天真和愚蠢的问题,但我会问这个问题

我有一个表有几个领域,没有一个是唯一的,主键,显然是。

该表通过非唯一字段定期访问,但没有用户SP或通过主键处理访问数据。 主键是否必要呢? 它在幕后使用吗? 删除它会影响性能积极还是消极?

必要? 号在幕后使用? 那么,它被保存到磁盘,并保存在行caching等。删除会稍微提高你的性能(使用毫秒级精度的手表注意到)。

但是…下一次有人需要创build这个表的引用,他们会诅咒你。 如果他们很勇敢,他们会添加一个PK(并等待很长时间DB创build列)。 如果他们不勇敢或愚蠢,他们将开始使用业务密钥(即数据列)创build引用,这将导致维护的噩梦。

结论:由于拥有PK(即使没有使用ATM)的成本太小,所以应该是这样。

你有没有外键,你有没有joinPK?

如果答案是否定的,并且你的应用程序永远不会从它的PK中检索表中的项目,并且没有任何查询在where子句中使用它,所以你只需要添加一个IDENTITY列来获得PK,那么:

  • PK本身没有增加任何价值,但也没有损害
  • 事实上,PK很可能是聚集索引也是.. 这取决于

如果你有NC索引,那么你有一个狭窄的人为聚簇键(IDENTITY PK)的事实有助于保持这些索引的缩小(在每个NC叶片槽中再现CDX键)。 因此,如果您有重要的数控指标,即使从未使用,PK也是有帮助的。

另一方面,如果您有一个stream行的访问模式,某个查询超过所有其他查询的频率和重要性,或者是关键时间代码path的一部分(例如,查询是在您网站的每个页面上访问,或每隔一秒和应用程序等),那么该查询是一个很好的候选人来指定聚集键序。

最后,如果表很less被查询,但经常被写入,那么它可能是HEAP的一个很好的候选者(根本就没有集群关键字),因为堆在插入上更好。 请参阅比较使用聚集索引与堆的表 。

主键在幕后clustered index (默认情况下除非生成为非聚簇索引)并保存表的所有数据。 如果PK是标识列,则插入将按顺序发生,并且不会发生页面拆分。

但是,如果您根本不访问id列,那么您可能希望在其他列上添加一些索引。 另外,当你有一个PK你可以设置FK关系

在逻辑模型中,一个表必须至less有一个键。 没有理由任意指定其中一个键是“主要”的。 所有的键都是平等的。 尽pipe“主键”的概念可以追溯到泰德·科德早期的工作,但早期的错误早已在关系理论中得到纠正。

不幸的是, PRIMARY KEY发现它是进入SQL的方式,从此我们不得不忍受它。 SQL表可以有重复的行,如果你认为SELECT查询的结果集也是一个表,那么SQL表也可以有重复行。 关系理论家很不喜欢SQL。 但是,仅仅因为SQL可以让你做各种古怪的非关系事物,这并不意味着你必须真正做到这一点。 确保每个SQL表至less有一个关键字是很好的做法。

在SQL中,使用PRIMARY KEY本身具有影响,例如NOT NULLUNIQUE ,这是表的缺省外键引用。 在SQL Server中,使用PRIMARY KEY本身具有影响,例如表的聚簇索引。 然而,在所有这些情况下,隐式行为可以使用特定的语法来明确。

您可以使用UNIQUE (约束而不是索引)和NOT NULL组合来强制SQL中的键。 因此,SQL Server中不需要主键(或者甚至PRIMARY KEY )。

我永远不会有一个没有主键的表。 假设你需要删除一个副本 – 你将如何识别哪一个删除,哪个要保留?

定义的主键将有助于提高数据库中索引和关系的性能。

我总是倾向于将主键定义为所有表中的自动递增整数,而不pipe我是否访问它,这是因为当您开始扩展应用程序时,可能会发现实际上需要它,使生活变得更简单。

主键实际上是您的域模型的一个属性,它唯一地标识了一个域对象的一个​​实例。

在单调递增的列(如标识列)上有一个聚簇索引将意味着页面拆分不会发生,但是插入操作会随着时间的推移使索引不平衡,因此重build索引需要定期完成(或者当碎片达到某个阈值时) 。

我必须有一个很好的理由来创build一个没有主键的表。

PK是没有必要的。

但是您应该考虑在用于查询的列上放置一个非唯一索引(即出现在WHERE子句中)。 这将大大提高查询性能。

HTH!
托马斯

如果您通过非关键字段访问它们,性能可能不会改变。 然而,为将来的增强或接口保留这些表可能会很好。 你的应用程序只使用这个表吗?

正如SQLMenace所说,聚簇索引是表的物理布局的一个重要列。 另外,有一个聚集索引,尤其是一个很好的select,像一个整数pk这样的瘦列,实际上增加了插入性能。