Подтвердить что ты не робот

Должен ли я использовать составные первичные ключи или нет?

Кажется, что только поддержка 2-го класса для составных ключей базы данных в Java JPA (через аннотации EmbeddedId или IdClass). И когда я читаю составные клавиши, независимо от языка, люди продолжают сталкиваться с тем, что они плохо работают. Но я не понимаю, почему. Сложные ключи все еще приемлемы для использования в эти дни? Если нет, почему бы и нет?

Я нашел одного человека, который согласен со мной: http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx

Но другой, кто этого не делает: http://weblogs.java.net/blog/bleonard/archive/2006/11/using_composite.html

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

Простой пример:

Actor { Id, Name, Email } Movie { Id, Name, Year } Character { Id, Name } Role { Actor, Movie, Character }

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

Но роль - это таблица соединений "Множество ко многим". Я не вижу смысла создавать идентификатор, чтобы идентифицировать строку в базе данных. Мне кажется очевидным, что первичный ключ { Actor, Movie, Character }. Это также кажется довольно ограниченной функцией, особенно если данные в таблице соединений постоянно меняются, вы можете столкнуться с первичными коллизиями после того, как первичная последовательность ключей обернется вокруг 0.

Итак, вернемся к исходному вопросу, все же приемлемой практикой является использование составных первичных ключей? Если нет, почему бы и нет?

4b9b3361

Ответ 1

Я думаю, что нет проблем с использованием составного ключа.

Для меня база данных это компонент сама по себе, которая должна рассматриваться так же, как мы рассматриваем код: например, мы хотим, чтобы чистый код, который четко передает свое намерение, делает одно и делает это хорошо, t добавить какой-либо неизменный уровень сложности и т.д.

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

db является базой вашего приложения, для меня нужна самая прочная база, которую мы можем иметь. На этой базе мы создадим приложение (сеть или нет). Поэтому я не понимаю, почему мы должны сгибать модель db, чтобы она соответствовала некоторым конкретным инструментам разработки /framework/language. Данные направляют приложение, а не наоборот. Что, если ORM изменится в будущем и станет устаревшим, и появится лучшее решение, которое накладывает другую модель? Мы не можем играть с моделью db в соответствии с той или иной структурой, модель должна оставаться неизменной, она не должна зависеть от того, какой инструмент мы используем для доступа к данным...

Если модель db изменится в будущем, она должна измениться, поскольку функциональность изменилась. Если бы мы сегодня знали, как эта функциональность изменится, мы уже будем ее моделировать. В случае каких-либо будущих изменений будет рассмотрено, когда придет время, мы не можем предсказать, например, влияние на существующие данные, поэтому один дополнительный столбец не гарантирует, что он будет отменять любые будущие изменения...

Мы должны разработать на сегодняшний день функциональность и сохранить модель db как можно более простое, таким образом, это будет легко изменить/эволюционировать в будущем.

Ответ 2

По моему личному мнению вам следует избегать составных первичных ключей из-за нескольких причин:

  • Будущие изменения: при разработке базы данных вы иногда пропускаете то, что в будущем станет важным. Важным примером этого является мысль о том, что комбинация из двух или более полей уникальна (и, следовательно, может стать первичным ключом), тогда как в будущем вы хотите разрешить NULL или другие неповторимые значения в них. Наличие одного первичного ключа - хорошее твердое решение против таких изменений.

  • Однородность: если каждая таблица имеет уникальный числовой идентификатор, и вы также поддерживаете некоторый стандарт относительно его имени (например, "ID" или "tablename_id" ), код и SQL, ссылающиеся на него, более ясны (в моем мнение).

Есть и другие причины, но это всего лишь несколько.

Главный вопрос, который я задал бы, - почему бы не использовать отдельный первичный ключ, если у вас есть уникальный набор полей? Какая стоимость? Дополнительный целочисленный индекс? Это не так уж плохо.

Надеюсь, что это поможет.

Ответ 3

Схожие вопросы были заданы на SO, и нет консенсуса;)

Если вы разрабатываете веб-приложение, вам понравится один столбец pk, поскольку они упрощают ваши URL-адреса.

Для обертывания последовательности вам потребуется 2 миллиарда записей в одной таблице (32 бит) или 10 ^ 18 с 64-разрядными версиями pk.

Btw, ваша модель данных не допускает персонажей фильма с неизвестными участниками.

Ответ 4

Мое общее мнение... нет. не используйте составные первичные ключи.

Они будут обычно усложнять ORM, если вы их используете (ORM иногда заходят так далеко, чтобы вызвать составные первичные ключи "унаследованное поведение" ), и, как правило, если вы используете несколько ключей, один или несколько из них будут иметь тенденцию быть скорее естественными чем технические ключи, для меня это большая проблема: ИМХО вы, безусловно, должны пользоваться техническими первичными ключами.

Подробнее об этом в Ошибки разработки баз данных, сделанные разработчиками приложений.

Ответ 5

Религиозные войны были и продолжают продолжаться по этому вопросу.

У людей есть эта ревностная вещь о "идентичности" и расскажет вам, что единственное, что имеет значение, это способность вас "идентифицировать" "объекты реальной жизни" внутри ваших программ и что составные, жизнь "ключи только попадут в неприятности при попытке достичь этой цели.

У данных людей есть эта вещь о "уникальности", которая воспринимается стороной "Ore" как "ревностная", и расскажет вам, что единственное, что имеет значение, это то, что если бизнес говорит вам, что комбинация атрибутов (значений для) X и атрибут Y должны быть уникальными, то ваша работа должна следить за тем, чтобы база данных применяла это бизнес-правило уникальности объединенного X + Y.

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

Ответ 6

Это религиозная вещь. Я использую естественные ключи и избегаю суррогатов. У меня нет проблем с составными ключами в теории или на практике.

Только самая тривиальная логическая модель не будет содержать составных клавиш. Назовите меня ленивым, но я не вижу необходимости усложнять модель данных, введя суррогаты в физическую модель реализации. Конечно, я бы рассмотрел один на столе, если были обнаружены проблемы с производительностью, но я использую тот же подход, что и для денормализации, т.е. В качестве крайней меры. Обычно использование суррогатов сводится к преждевременной оптимизации, ИМО.

Ответ 7

В Ruby for Rails, если явно не указано иное, ваша таблица Role будет похожа на вас (если столбцы на самом деле являются идентификаторами из других таблиц). Тем не менее, в базе данных вы можете захотеть обеспечить уникальные комбинации, указав уникальный индекс в этих трех столбцах, но только для того, чтобы помочь базе данных оптимизировать ваши запросы. С учетом этого уникального индекса и рамки, не использующей какой-либо другой первичный ключ, в вашей таблице Role нет необходимости в дополнительном числовом первичном ключе. Сказав это, уникальный индекс может быть определен как составной первичный ключ.

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

Итак: я бы использовал составные первичные ключи.

Ответ 8

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

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

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

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

Ответ 9

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

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

Ответ 10

Я почти никогда не видел случая, когда составной ключ был хорошей идеей (исключение, объединяющее таблицу, состоящую всего из двух суррогатных ключей). В первом пятне вы теряете пространство в детских таблицах. Вы наносите вред производительности в соединениях, поскольку объединения целых чисел, как правило, намного быстрее. Если у вас есть составной ключ в виде кластерного индекса (говорящий с SQL Server здесь), то вы заставляете базу данных быть менее эффективной в отношении хранения записей и менее эффективной при построении других индексов - все из которых используют индекс clusterd.

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

Итак, вы подумываете о том, чтобы использовать технику, которая наносит вред производительности, плохо использует память и хранилище баз данных, использует больше пространства в дочерних записях (другая трата ресурсов) и требует болезненного обновления того, что может быть миллионными дочерними записями, когда вещи меняются. И что может затруднить использование ОРМ? Почему ты бы так поступил? Потому что вам слишком ленив, чтобы наложить суррогатный ключ, а затем определить уникальный индекс потенциального составного ключа? Есть ли какая-либо прибыль от использования составного индекса? Из-за отсутствия 5-минутной работы вы постоянно наносили вред вашей базе данных?