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

Почему не хорошо иметь первичный ключ в таблице соединений?

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

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

Почему это нехорошо иметь первичный ключ в этом примере?

create_table :categories_posts, :id => false do |t|
  t.column :category_id, :integer, :null => false
  t.column :post_id, :integer, :null => false
end
add_index :categories_posts, :category_id
add_index :categories_posts, :post_id

EDIT: Как я уже упоминал в Cletus, я могу понять потенциальную полезность поля автоматического номера в качестве первичного ключа даже для таблицы соединений. Однако в приведенном выше примере автор явно избегает создания поля автоматического номера с синтаксисом ": id = > false" в инструкции "create table". Обычно Rails автоматически добавляет поле идентификатора автоматического номера в таблицу, созданную в результате миграции, как это, и это станет первичным ключом. Но для этой таблицы соединений автор специально предотвратил это. Я не был уверен, почему он решил следовать этому подходу.

4b9b3361

Ответ 1

Некоторые примечания:

  • Комбинация category_id и post_id уникальна сама по себе, поэтому дополнительный столбец ID является избыточным и расточительным
  • Фраза "нехорошо иметь первичный ключ" неверна в скринкасте. У вас все еще есть первичный ключ - он состоит только из двух столбцов (например, CREATE TABLE foo (cid, pid, PRIMARY KEY (cid, pid)). Для людей, которые используют для привязки к значениям идентификатора везде, это может показаться нечетным, но в реляционной теории это вполне корректно и естественно, автор скринкастов лучше сказал, что "нехорошо иметь неявный целочисленный атрибут, называемый" ID "в качестве первичного ключа".
  • У вас лишний столбец, потому что вы поместите уникальный индекс в комбинации category_id и post_id в любом случае, чтобы не было вставлено дублирующихся строк.
  • Наконец, хотя обычная номенклатура - это "составной ключ", это также избыточно. Термин "ключ" в реляционной теории на самом деле представляет собой набор из нуля или более атрибутов, которые однозначно идентифицируют строку, поэтому можно сказать, что первичный ключ - category_id, post_id
  • Поместите столбец MOST SELECTIVE FIRST в объявление первичного ключа. Обсуждение построения деревьев b (+/*) выходит за рамки этого ответа (для некоторых обсуждений на более низком уровне см. http://www.akadia.com/services/ora_index_selectivity.html), но в вашем случае вы, вероятно, захотите его на post_id, category_id, поскольку post_id будет отображаться реже в таблице и, таким образом, сделает индекс более полезным. Конечно, поскольку таблица настолько мала, и индекс будет, по сути, строками данных, это не очень важно. Это будет в более широких случаях, когда таблица будет шире.

Ответ 2

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

Ответ 3

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

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

Ответ 4

В основном потому, что в этом нет необходимости. Комбинация двух полей внешнего ключа достаточно однозначно идентифицирует любую строку.

Но это просто говорит, почему это не хорошая идея... но почему это была бы плохая идея?

Учитывайте, что добавление лишнего добавляет столбец идентификатора. В таблице потребуется 50% дискового пространства. Хуже всего ситуация индекса. С полем идентификации вам нужно сохранить количество идентификаторов, а также второй индекс. Вы удвоите дисковое пространство и утроите работу, которую необходимо выполнить для каждой вставки. Единственным преимуществом является немного более короткое предложение WHERE в команде DELETE.

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

Ответ 5

Плохая идея не иметь первичный ключ в любой таблице, периоде (если СУБД является реляционной СУБД или СУБД SQL). Первичные ключи являются важной частью целостности вашей базы данных.

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

Ответ 6

Размещение наиболее избирательного столбца сначала должно быть релевантным только в декларации INDEX. В объявлении KEY это не имеет значения (поскольку, как было правильно указано, KEY является SET, а внутри набора порядок не имеет значения - набор {a1, a2} является тем же самым набором, что и {a2 а1}).

Если продукт СУБД таков, что упорядочение атрибутов внутри объявления KEY имеет значение, тогда этот продукт СУБД виновен в неправильном различении логического дизайна базы данных (той части, где вы выполняете объявление KEY), и физический дизайн базы данных (часть, в которой вы делаете декларацию INDEX).

Ответ 7

Я хотел прокомментировать следующий комментарий: "Неправильно говорить" ноль или больше ".

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

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

Но когда я нажал кнопку "комментарий", система ответила мне, что для комментариев требуется оценка репутации 50 (или некоторых таких).

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

Ответ 8

Плюсы наличия одного ПК

  • Уникально идентифицирует строку с единственным значением
  • Легко ссылаться на связь из другого места, если это необходимо
  • Некоторые инструменты хотят, чтобы у вас было одно целочисленное значение pk

Против наличия одного ПК

  • Использует больше дискового пространства
  • Требуется 3 индекса, а не 1
  • Без уникального ограничения вы можете получить несколько строк для одинаковых отношений

Примечания

  • Вам нужно определить уникальное ограничение, если вы хотите избежать дубликатов
  • По-моему, не используйте одиночный pk, если вы столбец, будет огромным, иначе скомпенсируйте некоторое дисковое пространство для удобства. Да, это расточительно, но кто заботится о нескольких МБ на диске в реальных приложениях.