Зв'язок первинного ключа та кластерного індексу


92

Чи може TABLEмати первинний ключ без кластерного індексу?

А чи може TABLEмати кластерний індекс, не маючи первинного ключа?

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

Відповіді:


102

Первинний ключ - це логічне поняття - це унікальний ідентифікатор рядка в таблиці. Як такий, він має купу атрибутів - він може бути не нульовим, і він повинен бути унікальним. Звичайно, оскільки ви, ймовірно, будете багато шукати записи за їх унікальним ідентифікатором, було б добре мати індекс на первинному ключі.

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

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

Так, ви можете створити кластерний індекс для стовпців, які не є первинним ключем.


1
Привіт. Тема стара, але, можливо, хтось може відповісти на моє запитання. Якщо стовпець оголошено НЕ НУЛЬНИМ УНІКАЛЬНИМ КЛАСТЕРОВАНИМ ІНДЕКСОМ, чи зробить його ПЕРВИННИМ КЛЮЧОМ будь-які фактичні зміни в продуктивності чи щось інше?
jesse

Це цікаве питання. Я б припустив, що ні, оскільки він повинен виконувати всі однакові перевірки в будь-якому випадку.
Джонатан Аллен,

Блискуча відповідь.
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

Перш за все, погляньте на організовані за індексами таблиці та кластерні індекси . Насправді, я рекомендую прочитати цілу книгу. Використовуйте Індекс Луки! з самого початку, поки ви не дійдете до теми кластеризації, щоб по-справжньому зрозуміти, що відбувається.

Тепер до ваших запитань ...


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

Так, використовуйте ключове слово NONCLUSTERED при оголошенні первинного ключа для створення таблиці на основі купи. Наприклад:

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

Це прикро, оскільки багато людей, здається, просто приймають за замовчуванням (яке є КЛАСТЕРОВАНИМ), хоча в багатьох випадках таблиця на основі купи справді була б кращою (як обговорювалося у статті, на яку посилається).


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

На відміну від деяких інших СУБД, 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 за допомогою кластерних індексів

Чи може ТАБЛИЦЯ мати первинний ключ без кластерного індексу? - Так.

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

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

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

Ні-кластерний індекс являє собою логічний порядок рядків, з допомогою однієї (або більше) з її стовпців. Подумайте про це як про ще одну "копію" таблиці, упорядковану за будь-якими стовпцями, в яких знаходиться індекс.

Кластерний індекс це коли фактична таблиця фізично впорядкована за певною колонки. Таблиця не завжди матиме кластерний індекс (тобто, хоча вона буде фізично впорядкована чимось , ця річ може бути невизначеною ). Таблиця не може мати більше одного кластерного індексу, хоча вона може мати один складений кластерний індекс (тобто таблиця фізично упорядковується, наприклад, Прізвище, Ім'я, DOB).

PK часто (але не завжди) є кластерним індексом.


У SQL Server первинний ключ буде кластеризований за замовчуванням - якщо ви прямо не скажете, що це не так. Але це просто за замовчуванням - не вимога.
marc_s

Чи може таблиця мати первинний ключ без будь-якого індексу? Тому що, коли я кажу, що один стовпець є первинним ключем, за замовчуванням створюється кластерний індекс. При видаленні індексу таблиця більше не містить первинного ключа?
лютий

1

Для чого це може коштувати, у MS SQL Server усі стовпці первинного ключа повинні бути визначені як НЕ Нульові, тоді як створення унікального кластерного індексу цього не вимагає. Не впевнений щодо інших систем БД.


Це більше коментар до відповіді, позначеної як правильна.
Ян Догген,

1
Ласкаво просимо - Я даю вам +1, оскільки бачу, що у вас ще немає репутації для додавання коментарів. (Був там, зробив це :)
інженер з

0

Це може не стосуватися відповіді на це питання, але деякі важливі аспекти первинного ключа та кластерних індексів ->

Якщо існує первинний ключ (за замовчуванням це кластерний індекс, однак ми можемо це змінити) з кластерним індексом, тоді ми не можемо створити ще один кластерний індекс для цієї таблиці. Але якщо ще немає набору первинних ключів і є кластерний індекс, тоді ми не можемо створити первинний ключ за допомогою кластерного індексу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.