2011-05-31 78 views
51

可以在SQL Server CREATE TABLE语句内创建主键或唯一索引。是否可以在CREATE TABLE语句内创建一个非唯一索引?使用SQL Server在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语句中创建非唯一索引,而不是在它之后创建。

对于它的价值,我没有找到[SQL Server Books Online entry for CREATE TABLE]有帮助。

另外,[This Question]几乎相同,但接受的答案不适用。

回答

75

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

为什么你有这样一个要求,在CREATE TABLE语句中添加非唯一非聚簇索引?

注意的SQL Server 2014引入了inline index create option

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 
+14

感谢您的好解释!为什么?纯粹是出于美学原因。我认为如果所有的约束/索引都包含在同一个语句中,那么读取脚本可能会很方便。就我个人而言,我想知道属于外键的列是否也有索引,并且这可能是将这些信息在同一语句中进行逻辑分组的不错方法。 – Mike 2011-05-31 21:12:22

+0

我得到了'错误:(1146)表'tablename'不存在',哈哈哈,讽刺的 – 2016-11-03 14:23:03

7

这是一个单独的声明。

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

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

CLUSTERED | NONCLUSTERED
Indicate that a clustered or a nonclustered index is created for the PRIMARY KEY or UNIQUE constraint. PRIMARY KEY constraints default to CLUSTERED, and UNIQUE constraints default to NONCLUSTERED.

In a CREATE TABLE statement, CLUSTERED can be specified for only one constraint. If CLUSTERED is specified for a UNIQUE constraint and a PRIMARY KEY constraint is also specified, the PRIMARY KEY defaults to NONCLUSTERED.

您可以创建在PK场的指标,但不是在非PK非唯一约束领域的非聚集索引。

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

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

+0

感谢您的回答! BOL条目的索引位对于我来说并不足够明确,因为CREATE TABLE语句中的索引仅适用于“PRIMARY KEY或UNIQUE constraint [s]”,所以非常感谢您的理解! – Mike 2011-05-31 21:21:04

4

如何创建一个指数内嵌一个表创建脚本并没有为我工作,接受的答案。该做的:

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]) 
) 

记住,外键不创建索引,所以这是很好的做法,索引他们为你将很可能对他们的加盟。

+0

我没有遵循最后的声明。如果通常的做法是通过外键查询你的表,我会同意这种说法;但不仅仅是你加入它,因此它应该被索引。示例:查找所有员工及其公司名称X - 然后确定FK上的索引有帮助。查找所有员工及其公司名称,姓氏以A开头; FK上的索引不起作用。换句话说,我不确定“因为你加入它你应该索引它”是一个好习惯。我错过了什么吗? – Paul 2016-10-12 23:44:27

+0

索引使联接查询更快。 – ScubaSteve 2016-10-13 13:05:04

3

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 
) 

您也可以在线索引定义列之后另一条线,但内创建表语句,这使得多列索引,但仍然没有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) 
) 
相关问题