Связь первичного ключа и кластерного индекса

92

Может ли TABLE иметь первичный ключ без кластерного индекса?

И может ли TABLE иметь кластерный индекс без первичного ключа?

Может ли кто-нибудь вкратце рассказать мне о взаимосвязи между первичным ключом и кластеризованным индексом?

F11
источник

Ответы:

102

Первичный ключ - это логическая концепция - это уникальный идентификатор строки в таблице. Таким образом, у него есть набор атрибутов - он может быть не нулевым и должен быть уникальным. Конечно, поскольку вы, вероятно, будете часто искать записи по их уникальному идентификатору, было бы хорошо иметь индекс по первичному ключу.

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

Да, у вас может быть первичный ключ без кластеризованного индекса - а иногда вы можете захотеть (например, когда ваш первичный ключ представляет собой комбинацию внешних ключей в объединяемой таблице, и вы не хотите нести накладные расходы на перетасование диска при написании).

Да, вы можете создать кластерный индекс для столбцов, которые не являются первичным ключом.

Невилл Кейт
источник
1
Здравствуй. Тема старая, но может кто ответит на мой вопрос. Если столбец объявлен как NOT NULL UNIQUE CLUSTERED INDEX, сделает ли его PRIMARY KEY какое-либо фактическое изменение производительности или чего-то еще?
Джесси
Это интересный вопрос. Я бы предположил, что нет, поскольку он в любом случае должен выполнять все те же проверки.
Джонатан Аллен
Блестящий ответ.
NikosV
Но в большинстве случаев будет полезен столбец первичного ключа с кластеризованным индексом, поскольку он значительно упрощает поиск диапазона.
hunter_tech
34

Таблица может иметь некластеризованный первичный ключ, а для кластеризованной таблицы первичный ключ не требуется. Так что ответ на оба вопроса - да.

Кластеризованный индекс хранит все столбцы на конечном уровне. Это означает, что кластерный индекс содержит все данные в таблице. Таблица без кластерного индекса называется кучей.

Первичный ключ - это уникальный индекс, который по умолчанию кластеризован. По умолчанию означает, что при создании первичного ключа, если таблица еще не кластеризована, первичный ключ будет создан как кластерный уникальный индекс. Если вы явно не укажетеnonclustered параметр.

Пример, где t1имеет некластеризованный первичный ключ и t2не кластеризован, но имеет первичный ключ:

create table t1 (id int not null, col1 int);
alter table t1 add constraint PK_T1 primary key nonclustered (id);
create clustered index IX_T1_COL1 on t1 (col1);

create table t2 (id int not null, col1 int);
alter table t2 add constraint PK_T2 primary key nonclustered (id);

Пример в SQL Fiddle.

Андомар
источник
19

Прежде всего, взгляните на упорядоченные по индексу таблицы и кластерные индексы . На самом деле, я рекомендую прочитать полностью Use the Index Luke!site с самого начала, пока вы не дойдете до темы кластеризации, чтобы действительно понять, что происходит.

Теперь к вашим вопросам ...


Может ли ТАБЛИЦА иметь первичный ключ без кластерного индекса?

Да, используйте ключевое слово NONCLUSTERED при объявлении первичного ключа для создания таблицы на основе кучи. Например:

CREATE TABLE YOUR_TABLE (
    YOUR_PK int PRIMARY KEY NONCLUSTERED
    -- Other fields...
);

Это прискорбно, поскольку многие люди, кажется, просто принимают значение по умолчанию (которое CLUSTERED), хотя во многих случаях таблица на основе кучи на самом деле была бы лучше (как описано в связанной статье).


и Может ли ТАБЛИЦА иметь кластерный индекс без первичного ключа?

В отличие от некоторых других СУБД, MS SQL Server позволит вам иметь индекс кластеризации, отличный от первичного ключа, или даже без первичного ключа.

В следующем примере создается индекс кластеризации, отдельный от PK, который имеет ограничение UNIQUE поверх него, что вам, вероятно, нужно в большинстве случаев:

CREATE TABLE YOUR_TABLE (
    YOUR_PK int PRIMARY KEY,
    YOUR_CLUSTERED_KEY int NOT NULL UNIQUE CLUSTERED
    -- Other fields...
);

Если вы выберете неуникальный индекс кластеризации (используя CREATE CLUSTERED INDEX ...), MS SQL Server автоматически сделает его уникальным, добавив к нему скрытое поле.

Обратите внимание, что преимущества кластеризации наиболее заметны при сканировании диапазона. Если вы используете индекс кластеризации, который не "согласовывается" со сканированием диапазона, выполняемым вашим клиентским приложением (приложениями) (например, при чрезмерном использовании скрытого столбца, упомянутого выше, или кластеризации по суррогатному ключу ), вы в значительной степени побеждая цель кластеризации.


Кто-нибудь может вкратце рассказать мне о взаимосвязи первичного ключа и кластерного индекса?

В MS SQL Server первичный ключ также по умолчанию кластеризован . Вы можете изменить это значение по умолчанию, как описано выше.

Бранко Димитриевич
источник
4

Ответы взяты из MSDN с использованием кластерных индексов

Может ли ТАБЛИЦА иметь первичный ключ без кластерного индекса? - Да.

Может ли ТАБЛИЦА иметь кластерный индекс без первичного ключа? - Да.

Первичный ключ является сдерживающим фактором, который гарантирует уникальность значений, так что строка всегда можно идентифицировать конкретно этим ключом.

Индекс автоматически назначаются на первичный ключ (как строки часто «посмотрели» их первичный ключ).

Не-кластерный индекс представляет собой логический порядок строк, с помощью одной (или более) из ее столбцов. Думайте об этом как о еще одной «копии» таблицы, упорядоченной по столбцам, по которым находится индекс.

Кластерный индекс это когда фактическая таблица физически упорядочена по определенному столбцу. Стол не всегда будет иметь кластерный индекс (т.е. в то время как он будет физически по заказу что - то , что вещь может быть не определено ). Таблица не может иметь более одного кластеризованного индекса, хотя может иметь один составной кластерный индекс (т. Е. Таблица физически упорядочена, например, по фамилии, имени, дате рождения).

PK часто (но не всегда) является кластеризованным индексом.

Сепстер
источник
В SQL Server первичный ключ будет кластеризован по умолчанию - если вы явно не укажете, что это не так. Но это просто значение по умолчанию, а не требование.
marc_s
Может ли таблица иметь первичный ключ без индекса? Потому что, когда я говорю, что один столбец является первичным ключом, по умолчанию создается кластерный индекс. При удалении индекса таблица больше не содержит первичный ключ?
veljasije
1

Как бы то ни было, в MS SQL Server все столбцы в первичном ключе должны быть определены как НЕ NULL, в то время как создание уникального кластерного индекса не требует этого. Однако не уверен в других системах БД.

robotj
источник
Это скорее комментарий под ответом, помеченным как правильный.
Ян Догген,
1
Добро пожаловать - я ставлю вам +1, потому что вижу, что у вас еще нет репутации, чтобы добавлять комментарии. (Был там, сделал это :)
Reversed Engineer
0

Это может не относиться к ответу на этот вопрос, но некоторые важные аспекты первичного ключа и кластеризованных индексов ->

Если есть первичный ключ (по умолчанию, который является кластеризованным индексом, однако мы можем это изменить) с кластеризованным индексом, то мы не можем создать еще один кластерный индекс для этой таблицы. Но если первичный ключ еще не установлен, и есть кластеризованный индекс, то мы не можем создать первичный ключ с кластеризованным индексом.

Himanshupareek66
источник