Требуется ли MySQL первичный ключ для таблицы ссылок «многие ко многим»? - PullRequest
5 голосов
/ 07 декабря 2011

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

Я создаю базу данных для веб-галереи, которая будет содержать отношения «многие ко многим». Например, теги и изображения. Очевидно, что для этого будет создана третья таблица ссылок. Я вижу использование столбца первичного ключа в таблице тегов и в таблице изображений, но я не могу представить его использование в таблице ссылок. Это просто заняло бы место на сервере. Итак, я имею в виду просто не иметь столбец первичного ключа в таблице ссылок. MySQL позволяет это? Или будет ли какая-либо убедительная причина иметь первичный ключ в таблице ссылок? Спасибо.

Таблица ссылок:

+--------------+---------+-----------+
| primary key? | tag ids | image ids |
+--------------+---------+-----------+

Разъяснение

Разве не с первичным ключом в таблице сломает базу данных?

Ответы [ 4 ]

8 голосов
/ 07 декабря 2011

Не требуется, чтобы у вас был первичный ключ.

Однако также не требуется, чтобы первичным ключом было только одно поле. В этом случае вы можете объявить свой первичный ключ как (tag_id, image_id).

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

alter table link add primary key (tag_id, image_id);

НЕ говори

alter table link add primary key (tag_id + image_id);

(Я думаю, что "+" - это оператор конкатенации в MySQL. Это было давно. Стандарт SQL - "&", но MySQL использует это для чего-то другого.)

Существует большая разница между ними, а именно, в первом случае 25,34 и 253,4 являются двумя разными значениями, а во втором случае оба они превращаются в 2534.

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

create index link_tag_image on link(tag_id, image_id);
create index link_image_tag on link(image_id, tag_id);

Если вы делаете только первый (например), тогда рассмотрите этот запрос:

select tag.name
from image
join link on image.image_id=link.imagae_id
join tag on tag.tag_id=link.tag_id
where image.foo='bar'

Это выглядит достаточно правдоподобно: найдите все теги, которые соответствуют изображениям, которые соответствуют определенному условию. Но без второго индекса этот запрос может занять очень много времени, потому что БД придется последовательно читать всю таблицу ссылок, чтобы найти все записи с данным image_id.

6 голосов
/ 07 декабря 2011

Нет необходимости в первичном ключе в таблице ссылок. Хотя составной ключ это хорошая идея. Уникальность может быть достигнута с помощью UNIQUE (tag_ids, image_ids)

5 голосов
/ 07 декабря 2011

Да, ваш первичный ключ должен быть составным / составным ключом tag_id и image_id, т.е. PRIMARY KEY (tag_id, image_id).В этом случае нет необходимости в дополнительном автоинкрементном столбце.

0 голосов
/ 18 ноября 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...