4

创建表”语法显然不允许我指定集群外键约束。换句话说,这是非法的:

--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 FOREIGN KEY。

但这项调查让我更接近我的答案。显然聚集索引必须是唯一的,如此处所述。报价:

如果聚集索引不是唯一索引,则 SQL Server 通过添加一个内部生成的值(称为唯一符)使任何重复键唯一

特别是,我认为这个答案涵盖了它。

4

4 回答 4

4

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

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

请注意,正如@Martin Smith 所解释的,CONSTRAINT和的概念INDEX是不同的。各种 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)
) ;
于 2012-12-01T22:31:51.890 回答
4

这有什么理由吗?

您不妨问为什么不能创建CLUSTERED检查约束或CLUSTERED默认约束。

外键只定义了一个逻辑约束,并且在 SQL Server 中没有为它自动创建索引(这只发生在UNIQUEorPRIMARY KEY约束中)。在 SQL Server 中总是这样,如果您希望 FK 列被索引,您需要CREATE INDEX自己在相关列上运行 a。

因此 a 的概念CLUSTERED FOREIGN KEY没有任何意义。CLUSTERED INDEX正如您在问题中指出的那样,您当然可以在构成 FK 的列上创建一个。

于 2012-12-02T10:10:52.147 回答
2

一张表只能有一个聚集索引。默认情况下,这将是主键列。

有一些方法可以改变这一点- 您将需要使用PRIMARY KEY NONCLUSTEREDUNIQUE CLUSTERED FOREIGN KEY

于 2012-12-01T20:44:39.593 回答
0

您似乎将聚集索引的概念与键(主键或外键)混为一谈。为什么不先创建表,然后再指定其聚集索引?(从您的第一个示例中复制的代码并尽可能少地更改)

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

CREATE CLUSTERED INDEX IX_Content_Clustered on Content(ContentDefID)

您无需使聚集索引唯一

于 2012-12-02T11:10:43.400 回答