Почему первичные ключи имеют собственные имена?

19

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

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

Есть ли какое-то преимущество в использовании произвольных имен, которых я не вижу, или же СУБД не использует произвольные имена для первичных ключей?

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

Позвольте мне показать функцию, с помощью которой вы можете получить имена первичного ключа из имени его таблицы (используя ранние системные таблицы sql-sever или sybase):

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. Это произвольно, потому что это свойство таблицы. Имя таблицы - это все, что вам нужно знать, если вы хотите ее использовать.
bernd_k
источник

Ответы:

17

Первичные ключи (и другие уникальные ограничения) реализованы в виде индексов и обрабатываются точно так же - с точки зрения программиста не имеет смысла иметь отдельные пути кода для PK и индексов (это удвоило бы потенциал для ошибок).

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

Дэвид Спиллетт
источник
1
Да, это также означает, какой столбец используется, так как PK можно изменить. Так что для книг вы можете использовать ISBN в качестве ПК (который вы бы хотели называть ISBN, чтобы он был понятен), но затем, на полпути к разработке, вы можете решить, что вы можете также приобрести подержанные книги, то есть вы захотите отдельная запись (пример с макушки головы). Поэтому вам нужно изменить поле PK на какой-то уникальный идентификатор.
Натан Макиннес
1
Я бы предпочел фразу: «PK - это ограничение, использующее индекс» . Иногда два ограничения (PK и FK - или 2 FK) могут использовать один и тот же индекс.
ypercubeᵀᴹ
@ypercube Я предпочитаю «PK - это ограничение, которое использует индекс в 99,99% реальных баз данных» , что, конечно, означает, что возможно иметь ограничение PK без индекса, но никто не планирует использовать эту базу данных в Реальный мир когда-либо будет реализовывать его по причинам производительности.
Pacerier
6

Не уверен, что я полностью понимаю вопрос.

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

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

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

SQLRockstar
источник
5

Я бы сказал, что это деталь реализации для удобства чтения.

Constraint имена не являются обязательными (в SQL Server , по крайней мере), но я хотел бы иметь PK_MyTableдля MyTableнежелиPK_MyTabl___16feb6d8a

ГБН
источник
3

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

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

В свете этого имя PRIMARY KEY - это произвольное имя предпочтительного ключа-кандидата, присоединенного в качестве свойства таблицы. Может быть только один первичный ключ.

На самом деле создания только именных ключей-кандидатов должно быть достаточно.

Изменить индекс с кластерного на некластеризованный и обратно будет просто попыткой найти ПЕРВИЧНЫЙ КЛЮЧ, который по определению не больше 1. Полагаю, вы можете сказать, что определение PRIMARY KEY - это, по сути, чувство ностальгии по пуристам баз данных. Это чувство чистоты базы данных должно было вызывать уникальные ключи по ключевым словам CANDIDATE KEY вместо реальных слов UNIQUE KEY.

Нажмите здесь, чтобы увидеть определение ключа-кандидата и комментарии CJDate к нему

RolandoMySQLDBA
источник
1

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

mrdenny
источник