是SQL Server中必需的主键吗?

ror*_*yok 52 sql sql-server sql-server-2005

这可能是一个非常天真和愚蠢的问题,但无论如何我都会问它

我有一个包含多个字段的表,其中没有一个是唯一的,还有一个主键,显然是.

此表通过非唯一字段定期访问,但没有用户SP或进程通过主键访问数据.那么主键是必要的吗?它是在幕后使用的吗?删除它会影响性能的正面还是负面?

Aar*_*lla 45

必要?没有在幕后使用?好吧,它保存到磁盘并保存在行缓存等中.删除会略微提高性能(使用精度为毫秒精度的手表).

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

结论:由于PK的成本(即使它没有使用ATM)是如此之小,所以就这样吧.

  • 实际上:拥有一个主键(默认情况下也是集群键)实际上可以加快**SQL Server表上的许多操作 - 即使密钥本身并不是真正需要的.关键是:没有聚类键,表是一个"堆",它使用相当混乱的结构和组织.请参阅Kim Tripp的博客文章,详细解释群集密钥对您的表格的影响(作为一个积极的!):http://sqlskills.com/BLOGS/KIMBERLY/post/The-Clustered-Index- debate-Continues.aspx (25认同)
  • @ RemiDespres-Smyth:如果你使用**非唯一**键作为聚类键,那么SQL Server将需要将**uniqueifier**值(4字节)添加到那些重复的行 - 以**unquify**他们.那有什么意义呢?选择一个独特的键开始 - 更容易! (5认同)

Rem*_*anu 13

你有外国钥匙,你有没有加入PK?

如果答案是否定的,并且您的应用程序永远不会通过其PK从表中检索项目,并且没有查询在where子句中使用它,那么您只需添加IDENTITY列以获得PK,然后:

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

如果你有NC索引,那么你有一个狭窄的人工聚类密钥(IDENTITY PK)的事实有助于保持这些索引变窄(CDX密钥在每个NC叶子槽中再现).因此,如果您有重要的NC索引,即使从未使用PK,也会有所帮助.

另一方面,如果您有一个流行的访问模式,某个超过所有其他查询的查询是频率和重要性,或者是关键时间代码路径的一部分(例如,在您网站上每次访问页面时运行查询)或者每秒和app等)然后该查询是指示聚簇键顺序的良好候选者.

最后,如果表很少被查询但经常被写入,那么它可能是HEAP的良好候选者(根本没有集群密钥),因为堆在插入方面要好得多.请参阅比较使用群集索引与堆组织的表.


SQL*_*ace 5

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

但是,如果您根本不访问id列,则可能要在其他列上添加一些索引。另外,当您拥有PK时,您可以设置FK关系

  • “主键在幕后是聚集索引”-可能会误导人们。仅仅因为它是默认值,并不意味着它一定是(如您所知)。 (2认同)

one*_*hen 5

在逻辑模型中,一张表必须至少有一个键。没有理由武断地指定其中一个键是“主要的”;所有的键都是平等的。虽然“主键”的概念可以追溯到 Ted Codd 的早期工作,但这个错误很早就在关系理论中得到纠正。

可悲的是,PRIMARY KEY发现它进入了 SQL,从那时起我们就不得不忍受它。SQL 表可以有重复的行,如果您认为SELECT查询的结果集也是一个表,那么 SQL 表也可以有重复的行。关系理论家非常不喜欢 SQL。但是,仅仅因为 SQL 允许您执行各种古怪的非关系操作,并不意味着您必须实际执行这些操作。确保每个 SQL 表至少有一个键是一种很好的做法。

在 SQL 中,单独使用PRIMARY KEY具有含义,例如NOT NULLUNIQUE表的外键默认引用。在 SQL Server 中,单独使用PRIMARY KEY会产生影响,例如表的聚集索引。但是,在所有这些情况下,可以使用特定语法使隐式行为显式。

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