"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将有助于页面查找的性能。换句话说,“给我父母身份证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。
但这次调查让我更接近我的答案。显然clustered indexes MUST be unique,如此处所述。引用:
如果聚簇索引不是唯一索引,则SQL Server通过添加内部生成的称为唯一性的值来使任何重复键唯一
特别是,我认为this answer涵盖了它。
答案 0 :(得分: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)
) ;
答案 1 :(得分:4)
这有什么理由吗?
您也可以问为什么不能创建CLUSTERED
检查约束或CLUSTERED
默认约束。
外键只是定义了一个逻辑约束,并且在SQL Server中没有为它自动创建索引(这只适用于UNIQUE
或PRIMARY KEY
约束)。在SQL Server中总是如此,如果您希望索引FK列,则需要自己在相关列上运行CREATE INDEX
。
因此CLUSTERED FOREIGN KEY
的概念没有任何意义。当然,您可以在构成FK的列上创建CLUSTERED INDEX
,但正如您在问题中指出的那样。
答案 2 :(得分:2)
您只能在表上拥有一个聚簇索引。默认情况下,这将是主键列。
There are ways to change this - 您需要使用PRIMARY KEY NONCLUSTERED
和UNIQUE CLUSTERED FOREIGN KEY
。
答案 3 :(得分: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)
您无需使聚集索引唯一