是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 NULL
, UNIQUE
,这是表的缺省外键引用。 在SQL Server中,使用PRIMARY KEY
本身具有影响,例如表的聚簇索引。 然而,在所有这些情况下,隐式行为可以使用特定的语法来明确。
您可以使用UNIQUE
(约束而不是索引)和NOT NULL
组合来强制SQL中的键。 因此,SQL Server中不需要主键(或者甚至PRIMARY KEY
)。
我永远不会有一个没有主键的表。 假设你需要删除一个副本 – 你将如何识别哪一个删除,哪个要保留?
定义的主键将有助于提高数据库中索引和关系的性能。
我总是倾向于将主键定义为所有表中的自动递增整数,而不pipe我是否访问它,这是因为当您开始扩展应用程序时,可能会发现实际上需要它,使生活变得更简单。
主键实际上是您的域模型的一个属性,它唯一地标识了一个域对象的一个实例。
在单调递增的列(如标识列)上有一个聚簇索引将意味着页面拆分不会发生,但是插入操作会随着时间的推移使索引不平衡,因此重build索引需要定期完成(或者当碎片达到某个阈值时) 。
我必须有一个很好的理由来创build一个没有主键的表。
PK是没有必要的。
但是您应该考虑在用于查询的列上放置一个非唯一索引(即出现在WHERE子句中)。 这将大大提高查询性能。
HTH!
托马斯
如果您通过非关键字段访问它们,性能可能不会改变。 然而,为将来的增强或接口保留这些表可能会很好。 你的应用程序只使用这个表吗?
正如SQLMenace所说,聚簇索引是表的物理布局的一个重要列。 另外,有一个聚集索引,尤其是一个很好的select,像一个整数pk这样的瘦列,实际上增加了插入性能。