使用SQL Server在CREATE TABLE语句内创建非聚集的非唯一索引

问题描述

|| 可以在sql Server CREATE TABLE语句中创建主键或唯一索引。是否可以在CREATE TABLE语句中创建非唯一索引?
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语句中而不是之后创建非唯一索引。 对于它的价值,我没有发现[CREATE TABLE的sql Server联机丛书条目]会有所帮助。 同样,[此问题]几乎相同,但是接受的答案不适用。     

解决方法

        你不能。 CREATE / ALTER TABLE仅接受要添加的约束,不接受索引。主索引和唯一约束是根据索引来实现的,这是一个副作用。如您所知,要管理索引,您需要CREATE / ALTER / DROP INDEX。 为什么要在CREATE TABLE语句中添加非唯一性非聚集索引? 请注意,SQL Server 2014引入了内联索引创建选项:
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
    ,        根据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,e smallint NOT NULL
)
您还可以将内联索引定义为列之后的另一行,但是在create table语句中,这允许索引中有多个列,但仍然没有
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,e smallint NOT NULL,index IX_MyTable_c_d nonclustered (c,d)
)
    ,        这是一个单独的声明。 也不能插入表并从中选择并在同一条语句中建立索引。 BOL条目包含您需要的信息:   集群|已编排   表示   聚集索引或非聚集索引是   为PRIMARY KEY或UNIQUE创建   约束。主键约束   默认为CLUSTERED和UNIQUE   约束默认为NONCLUSTERED。      在CREATE TABLE语句中,CLUSTERED   只能指定一个   约束。如果指定了CLUSTERED   对于UNIQUE约束和PRIMARY   还指定了KEY约束,   PRIMARY KEY默认为NONCLUSTERED。 您可以在PK字段上创建索引,但不能在非pk非唯一约束字段上创建非聚集索引。 NCL索引与表的结构无关,也不是对表内部数据的约束。它是支持表格的独立实体,但并非其功能或设计所不可或缺的。 这就是为什么它是单独的声明。从设计角度来看,NCL索引与表无关(尽管有查询优化)。     ,        如何在表创建脚本中内联创建索引的可接受答案对我不起作用。这样做:
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])
)
请记住,外键不会创建索引,因此最好对它们建立索引,因为您很可能会加入它们。