Являются ли первичные ключи пассивными?
Какие уникальные функции предоставляют первичные ключи?
В то время как я назвал вопрос языком, твердо посаженным в щеку, мой вопрос серьезен. Прежде, чем начнется какое-либо пламя, я не говорю о создании базы данных без ограничений или ссылочной целостности. Однако, насколько я могу судить, SQL Server мог бы покончить с primary key
ключевое слово
- Уникальные индексы охватывают, ну, уникальность
- Не основанная на столбцах необнуляемость покрывает необнуляемость для PK
- ПК не должны быть кластеризованы, так что это не так
- Внешние ключи могут и часто реализуются с уникальными индексами, а не с PK
- Даже MSDN утверждает, что уникальный индекс создается для обеспечения уникальности ПК
Я согласен с тем, что логически первичный ключ вызывает некоторое недовольство моделью данных, но так ли это? [сарказм] О, и мы получаем эту маленькую иконку ключа, которую показывает SSMS при разработке таблицы! [/сарказм]
РЕДАКТИРОВАТЬ
Из комментариев видно, что я не задавал этот вопрос так ясно, как думал. Я согласен, что первичные ключи важны с логической точки зрения.
Я не спрашиваю:
- я должен выбрать INT или VARCHAR для моего ПК
- Нужно ли кластеризовать PK или как определить, что должно быть кластеризовано?
- как уникально идентифицировать строки
Я хотел спросить: "Какие функции предоставляет PK, которые не могут быть разумно реализованы с использованием других функций?" Я не предлагаю сходить с ума здесь - например, использовать триггер для обеспечения уникальности вместо уникальных ограничений / индексов. Разумное является ключевым словом здесь - и использование уникального индекса / ограничения кажется очень похожим на определение PK.
6 ответов
Совершенно другая точка зрения:
SQL - это язык, который определяется стандартом ISO. Этот стандарт имеет "обязательные" функции и "необязательное соответствие".
Если вы создаете СУБД с каким-либо языком манипулирования данными, то вы имеете право называть свой язык "SQL", только если:
(а) вы внедрили ВСЕ синтаксиса, предписанного стандартом ("обязательные" функции), и (б) все языковые функции, которые вы реализовали (все обязательные как минимум, но также и "необязательные") Вы "выбрали" для), выставить точно такое поведение, как определено / описано в стандарте.
Синтаксис "PRIMARY KEY" - очень старая функция, и весьма вероятно, что он является одним из тех "обязательных". Исключение слова из вашего языка означает, что вы больше не можете законно называть свой язык SQL. Крупные коммерческие поставщики вряд ли сделают такой шаг в ближайшее время.
Идея обозначения одного ключа на таблицу в качестве "первичного" по сути является излишней, устаревшей и во многих отношениях очень бесполезной.
Это излишне, потому что, по логике, все ключи могут выполнять одну и ту же функцию. Оставляя в стороне ограничения любой конкретной СУБД, логически говоря, "первичный" ключ обладает точно такими же возможностями и функциональностью, что и любой другой ключ той же таблицы. Поэтому обозначение одного ключа как "первичного" имеет такое же важное значение, как того хочет разработчик базы данных или пользователь. Различие является произвольным (это слово используется в EFCodd) и чисто психологическим (CJDate).
Эта концепция устарела, потому что в современной практике обычно таблицы имеют более одного ключа, а разные пользователи и потребители данных имеют разные "предпочтительные" или "наиболее значимые" идентификаторы для одного и того же фрагмента данных. Например: конечный пользователь может распознавать и использовать один ключ таблицы (часто тот, который называется "бизнес" или "естественный" ключ); программист среднего уровня, возможно, будет более заинтересован в другом ключе в той же таблице (например, "суррогатный" ключ); С другой стороны, администратор БД может рассматривать "кластерный" ключ как наиболее важный, или, возможно, он одинаково обеспокоен всеми ключами, имеющими индексы. Таким образом, предпочтительный или самый важный ключ зависит от точки зрения и предполагаемого использования - это вовсе не жесткая структурная особенность.
Концепция "первичного ключа" бесполезна по крайней мере по двум причинам. Во-первых, производители программного обеспечения для инструментов разработки баз данных, СУБД и инструментов моделирования, к сожалению, прикрепили все виды программных функций к ключам, обозначенным как "первичный ключ". Это на самом деле работает против оригинальной концепции. Нам больше не нужно просто выбирать один ключ на таблицу, что имеет логическое значение для дизайнера или пользователя. Мы поощряемся или даже вынуждены выбирать "первичные" ключи для поддержки той или иной функции в программном обеспечении X,Y или Z независимо от других соображений. Это очень прискорбно, потому что оно представляет собой ограничение и отсутствие гибкости в программном обеспечении. Мы должны быть свободны в выборе подходящего ключа для каждой цели и не ограничиваться одним ключом на таблицу для каждой цели.
Последняя причина, по которой первичные ключи бесполезны, заключается в том, что они бесполезно отвлекают от более важных вопросов проектирования баз данных. Концепция первичного ключа часто преувеличивается в образовании, в учебниках по проектированию баз данных и в повседневной практике управления данными. Зачастую это наносит ущерб или фактически исключает более фундаментальную проблему, то есть то, что все ключи и все другие ограничения целостности могут быть столь же важны для успешного проектирования и реализации базы данных.
Я часто утверждаю, что термин "первичный ключ" следует исключать и исключать из словаря управления данными, а также из программного обеспечения для управления данными.
Первичный ключ - это логическая концепция. Это ключ, который определяет идентичность объекта: в таблице виджетов каждый отдельный виджет отличается значением своего первичного ключа. PK не является кластеризованным индексом (то есть физическим свойством хранения) или уникальным ограничением (это другое логическое свойство). Хотя часто первичный ключ и кластеризованный ключ перекрываются, это просто совпадение (PK - удобный кластеризованный ключ) или даже просто халатность (PK используется как кластеризованный ключ, даже если для данной рабочей нагрузки существуют более подходящие кандидаты).
Изменение кластеризованного ключа - это изменение, которое может быть выполнено в любой момент, на месте, с помощью операций, чтобы лучше соответствовать требованиям к хранилищу или производительности рабочей нагрузки. Приложение не должно замечать изменения (в идеальном мире...). Изменение PK - это изменение дизайна, которое требует изменения модели данных приложения по мере изменения идентификатора объекта, и оно обычно просачивается через режим данных / код приложения.
Кстати, эта тема уже задавалась и отвечала на тошноту уже здесь:
- На какой столбец следует кластеризовать индекс?
- Должны ли первичные ключи всегда назначаться как кластерный индекс
- Должен ли я создать таблицу с первичным ключом varchar или int?
Чтобы немного уточнить разницу между PK и UNIQUE ограничениями: даже если есть несколько свойств, которые имеют уникальные ограничения и, следовательно, могут служить в качестве PK, только одно будет правильным выбором, они не равны. Какой из них полностью зависит от модели данных, от бизнеса, который означает сущность и что представляет каждое свойство. PK не важен для СУБД, СУБД действительно заботится о кластеризованном ключе и уникальности гораздо больше, чем о PK. PK предназначен для вас, разработчика и для вашего набора инструментов. Вы не хотите, чтобы каждый разработчик, указывающий на базу данных с помощью своего инструмента ORM, выбирал другой уникальный ключ в качестве идентификатора сущности, а затем каждый из них писал код, который сохраняет другое свойство в качестве идентификатора. Вы хотите, чтобы все выбрали один и тот же, первичный ключ, потому что у него есть другие атрибуты, в дополнение к уникальности. Главный пример - Стабильность, значение PK является стабильным в течение всего времени существования объекта (если нет, то PK был выбран неправильно).
Какие функции предоставляют PK, которые не могут быть разумно реализованы с использованием других функций?
Маленькая иконка SSMS. Серьезно, в конечном счете это то, к чему это сводится: PK передает дополнительную информацию, какой из возможных ключей является фактически тем, который идентифицирует объекты в таблице. Согласие, что зависимость от пути действительно играет существенную роль в сегодняшней позиции PK, но если бы не это, возникла бы какая-то другая конструкция, чтобы выполнить именно эту роль передачи намерений относительно логической модели.
Теоретически все ключи эквивалентны, но мы выбираем один из них в качестве "первичного" по психологическим и практическим причинам. Некоторые соображения:
- Поля PK автоматически НЕ NULL. Поля UNIQUE НЕ имеют значения NULL, только если вы укажете их как таковые (кстати, значения NULL в ограничении UNIQUE часто обрабатываются разными СУБД по-разному).
- Синтаксис FOREIGN KEY по умолчанию соответствует родительскому PK. Если вы хотите использовать родительское ограничение UNIQUE, вам нужно указать его явно.
- Кластеризация обычно основана на PK.
- PK часто отображается визуально отличным способом с помощью инструментов ER. Это может подтвердить, что (психологически) мы считаем один ключ более "важным", чем другие.
Во многом это является традицией - мы могли бы также легко иметь соглашения и инструменты, которые делают все ключи эквивалентными не только в теории, но и на практике, но история может быть мощной силой, даже в относительно молодой отрасли, такой как наша,
Вы указываете, что
логически первичный ключ требует немного намерения
и Аарон Бетранд указывает в комментариях
У вас может быть несколько уникальных ограничений или уникальных индексов, но только один из них должен быть тем способом, которым вы обычно ожидаете идентифицировать строку
Я предполагаю, что Аарон использовал такие слова, как должен, и обычно потому, что он знает, что даже для внешних ключевых ключей требуется только однозначное ограничение
Из документов MSDN по ограничениям SQL FOREIGN KEY
Ограничение FOREIGN KEY не обязательно должно быть связано только с ограничением PRIMARY KEY в другой таблице; его также можно определить для ссылки на столбцы ограничения UNIQUE в другой таблице
Кроме того, CJ Date также отмечает в Введение в системы баз данных
Если набор ключей-кандидатов на самом деле включает в себя более одного члена, то выбор, который должен быть первичным, по существу является произвольным *
Это приводит меня к выводу, что первичные ключи действительно не предоставляют ничего, кроме условных обозначений. Но это тот, который настолько сильно интегрирован в инструменты, которые мы используем, и в ментальные модели большинства людей, что его нельзя игнорировать.
* CJ Date объясняет здесь, что выбор первичного ключа не является полностью произвольным. Например, изменчивый первичный ключ был бы плохой идеей.
Первичные ключи автоматически индексируются во всех системах БД. (По крайней мере, в тех, которые я знаю до сих пор.)