Чому первинні ключі мають власні імена?


19

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

Як наслідок, щоб змінити первинний ключ з некластеризованого на кластеризований або навпаки, вам потрібно спочатку шукати його ім'я, ніж скидати його і, нарешті, читати його.

Чи є якась перевага у використанні довільних імен, яких я не бачу, чи є СУБД, які не використовують довільні імена для первинних ключів?

Змінити 2011-02-22 (22.02.2011 для тих, хто не хоче сортувати дату):

Дозвольте мені показати функцію, за допомогою якої ви можете отримати імена первинного ключа з назви його таблиць (використовуючи ранні sql-sever aka таблиці системних таблиць):

create function dbo.get_pk (@tablename sysname)
returns sysname
as
begin
    return (select k.name
    from sysobjects o 
        join sysobjects k   on k.parent_obj = o.id 
    where o.name = @tablename
    and o.type = 'U'
    and k.type = 'k')
end
go

Як зазначає gbn, нікому не дуже подобається створене ім’я, коли ви не вводите явного імені:

create table example_table (
    id int primary key
)

select dbo.get_pk('example_table')  

Я щойно отримав

PK__example___3213E83F527E2E1D

Але чому імена в sysobjects повинні бути унікальними. Було б цілком нормально використовувати точно таку ж назву для таблиці та її первинного ключа.

Роблячи це так, нам не потрібно було встановлювати конвенції про іменування, які могли бути випадково порушені.

Тепер відповіді Маріан:

  1. Я використовував лише завдання зміни кластеру в некластеризований первинний ключ як приклад, коли мені потрібно знати власне ім'я ПК, щоб мати можливість його скинути.
  2. Речі не повинні мати власних імен, достатньо, якщо їх можна легко однозначно позначити. Це основа абстракції. Об'єктно-орієнтоване програмування йде таким шляхом. Не потрібно використовувати різні імена для подібних властивостей різних класів.
  3. Це довільно, тому що це властивість таблиці. Назва таблиці - це все, що вам потрібно знати, якщо ви хочете її використовувати.

Відповіді:


17

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

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


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

1
Я вважаю за краще фразування: "ПК - це обмеження, яке використовує індекс" . Іноді два обмеження (PK і FK - або 2 FK) можуть використовувати один і той же індекс.
ypercubeᵀᴹ

@ypercube Я віддаю перевагу "ПК - це обмеження, яке використовує індекс у 99,99% реальних баз даних" , що, звичайно, означає, що можливе обмеження ПК без індексу, але ніхто не планує використовувати цю базу даних у реальний світ колись реалізовував би це через причини ефективності.
Печер'є

6

Не впевнений, що повністю розумію питання.

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

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

Я думаю, те саме можна сказати і для визначення стосунків ФК. Я думаю, що використання імен робиться для логічної інтерпретації, оскільки всі об'єкти мають різні об'єктиID.


5

Я б сказав, що це деталізація щодо людської читабельності.

Constraint імена НЕ є обов'язковими (в SQL Server , по крайней мере), але я хотів би мати PK_MyTableдля MyTableніжPK_MyTabl___16feb6d8a


3

Історично, Первинні та Унікальні Ключі називаються Ключами-кандидатами, як навчав Крістофер Дж. Дата.

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

Зважаючи на це, ім'я PRIMARY KEY - довільне ім'я кращого ключа-кандидата, доданого як властивість таблиці. Тут може бути лише один первинний ключ.

Насправді створення лише названих ключів-кандидатів повинно бути достатньо.

Змінення індексу з кластеризованого на некластеризований і назад було б просто вправою пошуку ПЕРВІЙНОГО КЛЮЧА, що становить максимум 1 за визначенням. Я думаю, ви можете сказати, що визначення ПЕРВИЧНОГО КЛЮЧУ - це, по суті, почуття ностальгії для пуристів бази даних. Це відчуття чистоти баз даних повинно було називати унікальні ключі за ключовими словами CANDIDATE KEY замість власне слів UNIQUE KEY.

Клацніть тут, щоб побачити визначення ключового ключа кандидата та коментарі CJDate до нього


1

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

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