Подтвердить что ты не робот

Создайте некластерный не уникальный индекс в инструкции CREATE TABLE с 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

Опять же, цель заключается в создании неидеального индекса внутри оператора CREATE TABLE, а не после него.

Для чего это стоит, я не нашел [SQL Server Books Online entry для CREATE TABLE], чтобы быть полезным.

Кроме того, [Этот вопрос] почти идентичен, но принятый ответ не применяется.

4b9b3361

Ответ 1

Вы не можете. 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

Ответ 2

Это отдельное утверждение.

Также невозможно вставить в таблицу и выбрать из нее и построить индекс в том же самом выражении.

Запись BOL содержит необходимую информацию:

КЛАСТЕРЕД | NONCLUSTERED
Показывают, что кластерный или некластеризованный индекс созданный для ПЕРВИЧНОГО КЛЮЧА или УНИКАЛЬНОГО ограничение. Ограничения PRIMARY KEY по умолчанию CLUSTERED и UNIQUE по умолчанию установлено значение NONCLUSTERED.

В инструкции CREATE TABLE, CLUSTERED может быть указана только для одного ограничение. Если указано CLUSTERED для УНИКАЛЬНОГО ограничения и ПЕРВИЧНОГО Также указывается ограничение KEY. PRIMARY KEY по умолчанию НЕ НЕОБХОДИМО.

Вы можете создать индекс в поле PK, но не некластеризованный индекс в не-pk не-уникальном ограниченном поле.

Индекс NCL не имеет отношения к структуре таблицы и не является ограничением для данных внутри таблицы. Это отдельный объект, поддерживающий таблицу, но не являющийся неотъемлемой частью его функциональности или дизайна.

Вот почему это отдельное утверждение. Индекс NCL не имеет отношения к таблице с точки зрения дизайна (несмотря на оптимизацию запросов).

Ответ 3

Принятый ответ о том, как создать Индекс, построил создание таблицы script, не работал у меня. Это произошло:

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

Помните, что внешние ключи не создают индексы, поэтому рекомендуется их индексировать, так как вы скорее присоединяетесь к ним.

Ответ 4

Согласно 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:

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