使用SQL Server在CREATE TABLE语句中创建非聚簇非唯一索引

Mik*_*ike 78 sql-server

可以在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
Run Code Online (Sandbox Code Playgroud)

同样,目标是在CREATE TABLE语句中创建非唯一索引,而不是在它之后.

对于它的价值,我没有找到[SQL Server联机丛书的CREATE TABLE条目]有用.

此外,[本课题]几乎相同,但接受的答案不适用.

Rem*_*anu 101

你不能.CREATE/ALTER TABLE仅接受要添加的CONSTRAINT,而不是索引.主键和唯一约束是根据索引实现的这一事实是副作用.要管理索引,您可以使用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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的解释!为什么?纯粹出于审美原因.我认为如果所有约束/索引都包含在同一语句中,那么读取脚本的任何人都会很方便.就个人而言,我想知道属于外键的列是否也有索引,这可能是一个很好的方法,可以在同一个语句中对此信息进行逻辑分组. (16认同)
  • 该索引是否可以包含“INCLUDE”列? (3认同)

Aar*_*nLS 12

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

<column_definition> ::=  
column_name <data_type>  
    ...
    [ <column_index> ]  
Run Code Online (Sandbox Code Playgroud)

和语法定义为:

<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" } ]  
Run Code Online (Sandbox Code Playgroud)

因此,您可以作为单独的语句执行的许多操作可以内联完成.我注意到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
)
Run Code Online (Sandbox Code Playgroud)

您还可以在列之后将内联索引定义为另一行,但是在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" } ]  

}   
Run Code Online (Sandbox Code Playgroud)

例如,我们在列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)
)
Run Code Online (Sandbox Code Playgroud)

  • 这很好用,根据 BOL 的说法,它至少可以追溯到 2008 年。像 OP 一样,我发现我最常看到的代码(通常由 SSMS 生成)让我的眼球受到伤害,而且我只是喜欢我的表格定义对一个理性的人有意义。谢谢。 (2认同)

JNK*_*JNK 8

这是一个单独的声明.

它也不可能插入到表中并从中进行选择并在同一语句中构建索引.

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

聚集| NONCLUSTERED
指示为PRIMARY KEY或UNIQUE约束创建聚簇索引或非聚簇索引.PRIMARY KEY约束默认为CLUSTERED,UNIQUE约束默认为NONCLUSTERED.

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

您可以在PK字段上创建索引,但不能在非pk非唯一约束字段上创建非聚集索引.

NCL索引与表的结构无关,并且不是对表内数据的约束.它是一个支持表格的独立实体,但不是其功能或设计的组成部分.

这就是为什么它是一个单独的声明.从设计角度来看,NCL索引与表无关(尽管有查询优化).


Scu*_*eve 6

如何创建索引内联表创建脚本的接受答案对我不起作用.这样做:

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])
)
Run Code Online (Sandbox Code Playgroud)

请记住,外键不会创建索引,因此最好将它们编入索引,因为您很可能会加入它们.

  • 索引使连接查询更快。 (2认同)