Как обрабатывать отношения «многие ко многим» с более чем 2 таблицами? - PullRequest
0 голосов
/ 15 мая 2011

Вот где я сейчас нахожусь.У меня есть четыре таблицы: задача, проект, возможность и task_xref.Каждая из таблиц проекта и возможностей имеет отношение «один ко многим» с задачей.Я храню эти отношения в task_xref.Схема выглядит примерно так для каждой таблицы (упрощенно):

task
----
id(pk)
name

project
-------
id(pk)
name
...

opportunity
-----------
id(pk)
name
...

task_xref
---------
task_id(task id)
fkey(other table id)

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

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

Вот возможные решения, о которых я подумал: 1) отдельная таблица внешних ссылок для каждой пары (например, task_project_xref, task_opportunity_xref ...) минусы: мне нужно выполнить запрос для каждой таблицы внешних ссылок, чтобы найти связи для задачи

2) третий столбец в task_xref, чтобы указать на минусы родительской таблицы: для меня это похоже на помойку

3) сохранить первичные ключи в проекте, возможность идентифицируемым способом (например, proj1, proj2, proj3, opp1, opp2, opp3), чтобы я мог сказать, к какой таблице относится задача, посмотрев на минусы fkey: thisТакое ощущение, что я делаю первичные ключи в проектах и ​​возможностях волшебными, наполняя их большим смыслом, чем просто идентификатором для одной записи (может быть, я слишком обдумываю это)

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

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

Я использую PHP и MySQL (в настоящее время таблицы MyISAM, но я буду использовать INNODB, если есть причина для этого).

Ответы [ 2 ]

0 голосов
/ 15 мая 2011

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

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

0 голосов
/ 15 мая 2011

Ваши SQL-соединения будут более точными, если у task_xref есть отдельные поля project_id и chance_id.Это хороший способ сделать это, потому что запросы просты.Кроме того, просто определить тип задачи, просто увидев, какой из внешних ключей не равен NULL.Это также эффективно.При объединении с задачами необходимы два запроса, поскольку проект и возможности, несомненно, будут иметь разную структуру, поэтому результаты в любом случае не могут быть union.

...