sql-server - T-SQL 聚集外键

标签 sql-server performance tsql foreign-keys

"Create Table" grammar显然不允许我指定聚集外键约束。换句话说,这是非法的:

--keyword CLUSTERED must be removed before this will execute...
CREATE TABLE [Content](
    [ID] [int] NOT NULL CONSTRAINT PK_Content_ID PRIMARY KEY,
    ContentDefID int NOT NULL CONSTRAINT FK_Plugin_ContentDef FOREIGN KEY CLUSTERED REFERENCES ContentDef(ID)
    )
GO

但我不明白为什么这是非法的。 ISTM 认为聚集外键将有助于分页查找的性能。换句话说,“给我父 ID 20 的子项目 80 到 140”。

这样做有什么道理吗?

更新

根据 Oded 和 Tvanfosson 的反馈,我发现以下方法有效:

CREATE TABLE [Content](
    [ID] [int] NOT NULL CONSTRAINT PK_Content_ID PRIMARY KEY,
    ContentDefID int NOT NULL UNIQUE CLUSTERED CONSTRAINT FK_ContentDefContent FOREIGN KEY REFERENCES ContentDef(ID)
    )
GO

但是上述引起的问题比它解决的问题还要多。首先,“唯一”外键迫使我的关系成为一对一,这是我不想要的。其次,这之所以有效,是因为它代表了两个单独约束的创建,而不是单个聚集外键。

但是这项调查让我更接近我的答案。显然clustered indexes MUST be unique ,如此处所述。引用:

If the clustered index is not a unique index, SQL Server makes any duplicate keys unique by adding an internally generated value called a uniqueifier

我特别认为this answer覆盖它。

最佳答案

正如其他人所解释的,聚集索引不必是主键,但它必须是唯一的,或者 SQL-Server 添加一个(未显示)UNIQUIFIER 列。

为了避免这种情况,您可以通过将主键列显式添加到聚集索引来使聚集索引唯一,如下所示。然后,该索引将可供外键约束使用(以及查询,例如连接两个表)。

请注意,正如 @Martin Smith 所解释的,CONSTRAINTINDEX 的概念是不同的。不同的 DBMS 以不同的方式实现这些。 SQL-Server 会自动为某些约束创建索引,但不会为外键约束创建索引。但建议有一个约束可以使用的索引(在引用的表中删除或更新时):

CREATE TABLE Content(
    ID int NOT NULL,
    ContentDefID int NOT NULL,
    CONSTRAINT PK_Content_ID 
      PRIMARY KEY NONCLUSTERED (ID),
    CONSTRAINT CI_Content
      UNIQUE CLUSTERED (ContentDefID, ID),
    CONSTRAINT FK_Plugin_ContentDef 
      FOREIGN KEY (ContentDefID) REFERENCES ContentDef(ID)
) ;

关于sql-server - T-SQL 聚集外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663569/

相关文章:

ruby-on-rails - 带有 Rails 5 应用程序的 Active-sqlserver-adapter。

tsql - 使用 FOR XML 进行行连接,但具有多列?

c# - 只读是否有任何运行时开销?

performance - 为什么reshape这么快? (剧透 : Copy-on-Write)

tsql - 组合 INSERT INTO 和 WITH/CTE

sql - 如何替换 DB varchar(6000) 中的 CHAR(13)?

sql - 如何从 NULL 列中获取值?

sql-server - SQL Server proc 的运行速度比普通查询慢 5 倍

php - PHP 和 mssql 库可以从 varchar 列中选择超过 256 个字符吗?

函数的计算速度