На работе у нас есть большая база данных с уникальными индексами вместо первичных ключей, и все работает нормально.
Я разрабатываю новую базу данных для нового проекта, и у меня возникает дилемма:
В теории БД первичный ключ является фундаментальным элементом, это нормально, но в РЕАЛЬНЫХ проектах каковы преимущества и недостатки обоих?
Что вы используете в проектах?
РЕДАКТИРОВАТЬ: ... а как насчет первичных ключей и репликации на сервере MS SQL?
sql
database
database-design
Cicik
источник
источник
Ответы:
Что такое уникальный индекс?
Уникальный индекс в столбце - это индекс в этом столбце, который также обеспечивает ограничение, согласно которому вы не можете иметь два равных значения в этом столбце в двух разных строках. Пример:
Последняя вставка не удалась, потому что она нарушает уникальный индекс столбца,
foo
когда пытается вставить значение 1 в этот столбец во второй раз.В MySQL уникальное ограничение допускает несколько значений NULL.
Можно создать уникальный индекс для нескольких столбцов.
Первичный ключ против уникального индекса
То же самое:
Вещи, которые разные:
источник
Вы можете увидеть это так:
Первичный ключ уникален
Уникальное значение не обязательно должно быть представлением элемента.
Смысл?; Ну, первичный ключ используется для идентификации элемента, если у вас есть «Человек», вы хотели бы иметь личный идентификационный номер (SSN или такой), который является основным для вашего человека.
С другой стороны, у человека может быть электронное письмо, которое уникально, но не идентифицирует человека.
У меня всегда есть первичные ключи, даже в таблицах отношений (средняя таблица / таблица соединений) они могут быть у меня. Зачем? Что ж, мне нравится следовать стандарту при кодировании, если "Человек" имеет идентификатор, а Автомобиль имеет идентификатор, тогда Человек -> Автомобиль также должен иметь идентификатор!
источник
Внешние ключи работают с уникальными ограничениями, а также с первичными ключами. Из электронной книги:
Для репликации транзакций вам понадобится первичный ключ. Из книг в Интернете:
Оба ответа предназначены для SQL Server 2005.
источник
Выбор того, когда использовать суррогатный первичный ключ вместо естественного ключа, является сложным. Такие ответы, как «всегда или никогда», редко бывают полезными. Я считаю, что это зависит от ситуации.
В качестве примера у меня есть следующие таблицы:
У нас есть две таблицы сущностей (
toll_booths
иcars
) и таблица транзакций (drive_through
). Вtoll_booth
таблице используется суррогатный ключ, поскольку он не имеет естественного атрибута, изменение которого не гарантируется (имя можно легко изменить). Вcars
таблице используется естественный первичный ключ, потому что он имеет неизменяемый уникальный идентификатор (vin
). Таблицаdrive_through
транзакций использует суррогатный ключ для легкой идентификации, но также имеет уникальное ограничение на атрибуты, которые гарантированно будут уникальными во время вставки записи.На http://database-programmer.blogspot.com есть несколько отличных статей по этой конкретной теме.
источник
У первичных ключей нет недостатков.
Чтобы добавить только некоторую информацию к ответам @MrWiggles и @Peter Parker, когда таблица не имеет первичного ключа, например, вы не сможете редактировать данные в некоторых приложениях (в конечном итоге они скажут, что не могут редактировать / удалять данные без основной ключ). Postgresql позволяет нескольким значениям NULL находиться в столбце UNIQUE, PRIMARY KEY не допускает значений NULL. Также некоторые ORM, генерирующие код, могут иметь проблемы с таблицами без первичных ключей.
ОБНОВИТЬ:
Насколько я знаю, в MSSQL невозможно реплицировать таблицы без первичных ключей, по крайней мере, без проблем ( подробности ).
источник
Если что-то является первичным ключом, в зависимости от вашего механизма БД вся таблица сортируется по первичному ключу. Это означает, что поиск по первичному ключу выполняется намного быстрее, потому что он не требует никакого разыменования, как это имеет место с любым другим типом индекса. Кроме того, это всего лишь теория.
источник
В дополнение к тому, что было сказано в других ответах, для некоторых баз данных и систем может потребоваться наличие первичного. На ум приходит одна ситуация; при использовании корпоративной репликации с Informix должен присутствовать PK, чтобы таблица могла участвовать в репликации.
источник
Пока вы не разрешаете NULL для значения, они должны обрабатываться одинаково, но значение NULL обрабатывается по-разному в базах данных (AFAIK MS-SQL не допускает более одного (1) значения NULL, mySQL и Oracle допускают это , если столбец UNIQUE) Таким образом, вы должны определить этот столбец NOT NULL UNIQUE INDEX
источник
В теории реляционных данных не существует такого понятия, как первичный ключ, поэтому на ваш вопрос нужно ответить на практическом уровне.
Уникальные индексы не являются частью стандарта SQL. Конкретная реализация СУБД будет определять, каковы последствия объявления уникального индекса.
В Oracle объявление первичного ключа приведет к созданию уникального индекса от вашего имени, поэтому вопрос почти спорный. Не могу рассказать о других продуктах СУБД.
Я предпочитаю объявить первичный ключ. Это приводит к запрету значений NULL в ключевом столбце (ах), а также к запрету дублирования. Я также предпочитаю объявлять ограничения REFERENCES для обеспечения целостности объекта. Во многих случаях объявление индекса в поле (ах) внешнего ключа ускоряет соединения. Такой индекс, как правило, не должен быть уникальным.
источник
У КЛАСТЕРИРОВАННЫХ ИНДЕКСОВ по сравнению с УНИКАЛЬНЫМИ ИНДЕКСАМИ есть некоторые недостатки.
Как уже говорилось, КЛАСТЕРНЫЙ ИНДЕКС физически упорядочивает данные в таблице.
Это означает, что когда у вас есть много вставок или удалений в таблице, содержащей кластеризованный индекс, каждый раз (ну, почти, в зависимости от коэффициента заполнения) вы меняете данные, физическая таблица должна обновляться, чтобы оставаться отсортированной.
В относительно небольших таблицах это нормально, но когда вы переходите к таблицам с объемом данных в ГБ, а операции вставки / удаления влияют на сортировку, вы столкнетесь с проблемами.
источник
Я почти никогда не создаю таблицу без числового первичного ключа. Если есть еще естественный ключ, который должен быть уникальным, я также помещаю на него уникальный индекс. Соединения для целых чисел выполняются быстрее, чем для многоколоночных естественных ключей, данные должны изменяться только в одном месте (естественные ключи, как правило, необходимо обновлять, что плохо, когда они находятся в отношениях первичный ключ - внешний ключ). Если вам понадобится репликация, используйте GUID вместо целого числа, но по большей части я предпочитаю ключ, который читается пользователем, особенно если им нужно увидеть его, чтобы различать Джона Смита и Джона Смита.
Несколько раз я не создаю суррогатный ключ, когда у меня есть соединяющая таблица, которая участвует в отношении «многие ко многим». В этом случае я объявляю оба поля первичными ключами.
источник
Насколько я понимаю, первичный ключ и уникальный индекс с ненулевым ограничением - это одно и то же (*); и я предполагаю, что кто-то выберет тот или иной в зависимости от того, что явно указано или подразумевается в спецификации (вопрос того, что вы хотите выразить и явно обеспечить). Если для него требуется уникальность, а не значение NULL, сделайте его первичным ключом. Если так получилось, что все части уникального индекса не равны нулю без каких-либо требований, просто сделайте его уникальным индексом.
Единственное остающееся различие заключается в том, что у вас может быть несколько уникальных индексов, не равных нулю, и не может быть несколько первичных ключей.
(*) За исключением практического различия: первичный ключ может быть уникальным ключом по умолчанию для некоторых операций, таких как определение внешнего ключа. Ex. если определить внешний ключ, ссылающийся на таблицу, и не указать имя столбца, если указанная таблица имеет первичный ключ, то первичный ключ будет столбцом, на который указывает ссылка. В противном случае столбец, на который указывает ссылка, должен быть назван явно.
Другие здесь упоминали репликацию БД, но я не знаю об этом.
источник
Уникальный индекс может иметь одно значение NULL. Создает НЕКЛАСТЕРНЫЙ ИНДЕКС. Первичный ключ не может содержать значение NULL. Создает КЛАСТЕРНЫЙ ИНДЕКС.
источник
В MSSQL первичные ключи должны монотонно увеличиваться для лучшей производительности кластеризованного индекса. Поэтому целое число со вставкой идентификатора лучше, чем любой естественный ключ, который может не увеличиваться монотонно.
источник
Если бы это было до меня ...
Вам необходимо удовлетворить требования базы данных и ваших приложений.
Добавление в каждую таблицу столбца с автоматически увеличивающимся целым числом или длинным идентификатором в качестве первичного ключа обеспечивает соблюдение требований к базе данных.
Затем вы должны добавить по крайней мере еще один уникальный индекс в таблицу для использования вашим приложением. Это может быть индекс для employee_id, account_id, customer_id и т. Д. Если возможно, этот индекс не должен быть составным индексом.
Я бы предпочел индексы по нескольким полям индивидуально, а не составные индексы. База данных будет использовать индексы одного поля всякий раз, когда предложение where включает эти поля, но она будет использовать составной только тогда, когда вы предоставите поля в точном правильном порядке, то есть она не может использовать второе поле в составном индексе, если вы не предоставите как первое, так и второе в вашем предложении where.
Я полностью сторонник использования вычисляемых индексов или индексов функционального типа и рекомендую использовать их вместо составных индексов. Это позволяет очень легко использовать индекс функции, используя ту же функцию в предложении where.
Это позаботится о ваших требованиях к приложению.
Весьма вероятно, что другие непервичные индексы на самом деле отображают значение ключа этого индекса в значение первичного ключа, а не в rowid (). Это позволяет выполнять операции физической сортировки и удаления без повторного создания этих индексов.
источник