使用SQL Server在CREATE TABLE语句中创build一个非聚集的非唯一索引

可以在SQL Server CREATE TABLE语句中创build主键或唯一索引。 是否可以在CREATE TABLE语句中创build一个非唯一索引?

CREATE TABLE MyTable( a int NOT NULL ,b smallint NOT NULL ,c smallint NOT NULL ,d smallint NOT NULL ,e smallint NOT NULL -- This creates a primary key ,CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED (a) -- This creates a unique nonclustered index on columns b and c ,CONSTRAINT IX_MyTable1 UNIQUE (b, c) -- Is it possible to create a non-unique index on columns d and e here? -- Note: these variations would not work if attempted: -- ,CONSTRAINT IX_MyTable2 INDEX (d, e) -- ,CONSTRAINT IX_MyTable3 NONCLUSTERED INDEX (d, e) ); GO -- The proposed non-unique index should behave identically to -- an index created after the CREATE TABLE statement. Example: CREATE NONCLUSTERED INDEX IX_MyTable4 ON MY_TABLE (d, e); GO 

再次,目标是在CREATE TABLE语句中创build非唯一索引,而不是在它之后。

对于它的价值,我没有find[SQL Server联机丛书CREATE TABLE]条目是有帮助的。

另外, [这个问题]几乎是相同的,但是接受的答案不适用。

你不能。 CREATE / ALTER TABLE只接受要添加的CONSTRAINT,而不接受索引。 主键和唯一性约束是以索引来实现的,这是一个副作用。 为了pipe理索引,你已经知道了CREATE / ALTER / DROP INDEX。

为什么你需要在CREATE TABLE语句中添加非唯一非聚簇索引?

请注意,SQL Server 2014引入了内联索引创build选项 :

 CREATE TABLE MyTable( a int NOT NULL ,b smallint NOT NULL ,c smallint NOT NULL ,d smallint NOT NULL ,e smallint NOT NULL -- This creates a primary key ,CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED (a) -- This creates a unique nonclustered index on columns b and c ,CONSTRAINT IX_MyTable1 UNIQUE (b, c) -- This creates a non-clustered index on (d, e) ,INDEX IX_MyTable4 NONCLUSTERED (d, e) ); GO 

这是一个单独的声明。

也不可能插入到表中并从中select并在同一语句中构build索引。

BOL条目包含您需要的信息:

集群| NONCLUSTERED
指示为PRIMARY KEY或UNIQUE约束创build了聚簇索引或非聚簇索引。 PRIMARY KEY约束默认为CLUSTERED,UNIQUE约束默认为NONCLUSTERED。

在CREATE TABLE语句中,只能为一个约束指定CLUSTERED。 如果为UNIQUE约束指定了CLUSTERED,并且还指定了PRIMARY KEY约束,则PRIMARY KEY默认为NONCLUSTERED。

您可以在PK字段上创build索引,但不在non-pk非唯一约束字段上创build非聚簇索引。

NCL索引与表的结构无关,并且不是表内数据的约束。 它是一个独立的实体,支持表,但不是它的function或devise的组成部分。

这就是为什么这是一个单独的声明。 从deviseangular度来看,NCL索引与表无关(查询优化尽pipe)。

如何创build索引内联表创build脚本接受的答案不适用于我。 这样做:

 CREATE TABLE [dbo].[TableToBeCreated] ( [Id] BIGINT IDENTITY(1, 1) NOT NULL PRIMARY KEY ,[ForeignKeyId] BIGINT NOT NULL ,CONSTRAINT [FK_TableToBeCreated_ForeignKeyId_OtherTable_Id] FOREIGN KEY ([ForeignKeyId]) REFERENCES [dbo].[OtherTable]([Id]) ,INDEX [IX_TableToBeCreated_ForeignKeyId] NONCLUSTERED ([ForeignKeyId]) ) 

请记住,外键不会创build索引,所以最好将它们编入索引,因为您将更有可能join它们。

根据T-SQL CREATE TABLE文档,在2014年,列定义支持定义一个索引:

 <column_definition> ::= column_name <data_type> ... [ <column_index> ] 

和语法被定义为:

 <column_index> ::= INDEX index_name [ CLUSTERED | NONCLUSTERED ] [ WITH ( <index_option> [ ,... n ] ) ] [ ON { partition_scheme_name (column_name ) | filegroup_name | default } ] [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ] 

所以很多你可以作为一个单独的语句可以做内联。 我注意到include在这个语法中不是一个选项,所以有些东西是不可能的。

 CREATE TABLE MyTable( a int NOT NULL ,b smallint NOT NULL index IX_MyTable_b nonclustered ,c smallint NOT NULL ,d smallint NOT NULL ,e smallint NOT NULL ) 

您也可以将内联索引定义为列之后的另一行,但在create table语句中,这允许索引中include多个列,但仍然不include子句:

 < table_index > ::= { { INDEX index_name [ CLUSTERED | NONCLUSTERED ] (column_name [ ASC | DESC ] [ ,... n ] ) | INDEX index_name CLUSTERED COLUMNSTORE | INDEX index_name [ NONCLUSTERED ] COLUMNSTORE (column_name [ ,... n ] ) } [ WITH ( <index_option> [ ,... n ] ) ] [ ON { partition_scheme_name (column_name ) | filegroup_name | default } ] [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ] } 

例如,在这里我们在列c和d上添加一个索引:

 CREATE TABLE MyTable( a int NOT NULL ,b smallint NOT NULL index IX_MyTable_b nonclustered ,c smallint NOT NULL ,d smallint NOT NULL ,e smallint NOT NULL ,index IX_MyTable_c_d nonclustered (c,d) )