Лучший способ хранить отношения многие ко многим в MySQL? - PullRequest
4 голосов
/ 30 июня 2010

Допустим, у меня есть простая база данных с таблицами 'posts' и 'tags'. Сообщения могут иметь много тегов, а теги могут принадлежать многим сообщениям.

Каков наилучший способ структурировать базу данных? Я думал об использовании списка / сериализации:

tags
idx tag_id, str tag_name

posts
idx post_id, str title, list tag_ids

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

posts
idx post_id, str title

post_tags
fk post_id, fk tag_id

Мне на самом деле не нравится ни один из них. Есть ли лучший способ?

Ответы [ 5 ]

19 голосов
/ 30 июня 2010

post_tags - это правильное средство реализации связи «многие ко многим» в базе данных.

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

3 голосов
/ 30 июня 2010

Вы почти наверняка захотите использовать "пересечение" или таблицу соединений.Эта таблица может содержать первичные ключи таблицы posts и tags и (необязательно) собственный отдельный первичный ключ.Присоединение к трем таблицам должно быть простым:

select ...
from post_tags
inner join posts on post_tags.postID = posts.postID
inner join tags on post_tags.tagID = tags.tagID
...

Вы можете создать представление, которое выполняет базовое объединение, которое затем можно ссылаться в своем коде.

2 голосов
/ 30 июня 2010

Используйте таблицу с ассоциациями - она ​​называется соединительной таблицей .

Чтобы получить теги для сообщения:

SELECT tag_name FROM tags, post_tags WHERE post_tags.tag_id = tags.tag_id AND post_tags.post_id = 12345;
0 голосов
/ 01 июля 2010

Я думаю, что это хорошее объяснение, чтобы начать с: http://www.tonymarston.net/php-mysql/many-to-many.html

В противном случае вы должны взглянуть на объектное реляционное отображение - которое выполняет сложные SQL-запросы для вас.

Дляпример: http://www.qcodo.com/

0 голосов
/ 30 июня 2010

Использовать таблицу соединений

...