Существует ли SQL Server 2008 эквивалент предложения USING INDEX в Oracle? Специально для конструкции:
CREATE TABLE c(c1 INT, c2 INT);
CREATE INDEX ci ON c (c1, c2);
ALTER TABLE c ADD CONSTRAINT cpk PRIMARY KEY (c1) USING INDEX ci;
В документации Sql Server по уникальным индексам говорится (выделено):
Уникальные индексы реализуются следующими способами:
ПЕРВИЧНЫЙ КЛЮЧ или УНИКАЛЬНОЕ ограничение
При создании ограничения PRIMARY KEY уникальный кластеризованный индекс для столбца или столбцов создается автоматически, если кластеризованный индекс в таблице еще не существует и вы не указываете уникальный некластеризованный индекс . Столбец первичного ключа не может принимать значения NULL.
Что, по-видимому, подразумевает, что существует способ указать, какой индекс следует использовать для первичного ключа.
create table c (c1 int not null primary key, c2 int)
Ответы:
Нет. При создании первичного ключа или уникального ограничения в SQL Server автоматически создается уникальный индекс для поддержки этого ограничения с теми же ключами.
Нет. Документация только пытается объяснить, будет ли автоматический вспомогательный индекс создаваться как кластеризованный или некластеризованный, если вы не укажете. Это смешно сформулировано, я согласен.
Для пояснения, когда вы добавляете ограничение первичного ключа в существующую таблицу без выражения предпочтения, вспомогательный индекс будет кластеризован, если в таблице нет ранее существующего кластеризованного индекса. Поддерживающий индекс будет создан как некластеризованный, если кластерный индекс уже существует
Вы можете специально запросить кластерный или некластерный первичный ключ, используя:
PRIMARY KEY CLUSTERED
илиPRIMARY KEY NONCLUSTERED
.Справедливости ради, документация намного яснее по этому вопросу:
table_constraint (Transact-SQL)
источник
Синтаксис SQL Server для создания кластерного индекса, который также является первичным ключом:
Что касается вашего комментария: «заставить PK использовать именованный индекс», приведенный выше код приведет к тому, что индекс первичного ключа будет назван «PK_c».
Первичный ключ и ключ кластеризации не обязательно должны быть одинаковыми столбцами. Вы можете определить их отдельно. В приведенном выше примере измените
CLUSTERED
ключевое слово наNONCLUSTERED
, а затем просто добавьте кластерный индекс, используяCREATE INDEX
синтаксис:В SQL Server кластеризованный индекс - это таблица, они одно и то же. Кластерный индекс определяет логический порядок строк, хранящихся в таблице. В моем первом примере, строки хранятся в порядке значений
c1
иc2
столбцов. Поскольку ключ кластеризации также определяется как первичный ключ, комбинацияc1
иc2
должна быть уникальной для всей таблицы.Во втором примере, первичный ключ состоит из
c1
иc2
столбцов, однако ключ кластеризации является толькоc2
столбец. Поскольку я не указалUNIQUE
атрибут вCREATE INDEX
заявлении, ключ кластеризации (c2
) не обязательно должен быть уникальным по всей таблице. «Uniquifier» будет автоматически создан SQL Server и добавлен к значениям вc2
столбце для создания ключа кластеризации. Этот ключ кластеризации, поскольку он теперь уникален, будет затем использоваться в качестве идентификатора строки в других индексах, созданных в таблице.Чтобы доказать, что ключ кластеризации контролирует расположение строк в хранилище, вы можете использовать недокументированную функцию
fn_PhysLocCracker(%%PHYSLOC%%)
. Следующий код показывает, что строки располагаются на диске в порядкеc2
столбца, который я определил как ключ кластеризации:Результаты из моей базы данных:
На изображении выше первые три столбца выводятся из
fn_PhysLocCracker
функции, показывая физическое упорядочение строк на диске. Вы можете видеть, чтоslot_id
значение увеличивает шаг блокировки соc2
значением, которое является ключом кластеризации. Индекс первичного ключа хранит строки в другом порядке, что можно увидеть, заставив SQL Server возвращать результаты сканирования первичного ключа:Обратите внимание, я не использовал
ORDER BY
предложение в приведенном выше утверждении, так как я пытаюсь показать порядок элементов в индексе первичного ключа.Выходные данные из вышеприведенного запроса:
Что касается
fn_PhysLocCracker
функции, мы можем видеть физический порядок индекса первичного ключа.Поскольку мы читаем исключительно из самого индекса, то есть в запросе нет ссылок на столбцы вне индекса,
%%PHYSLOC%%
значения представляют страницы в самом индексе.Результаты:
источник