Отношение один ко многим в одной таблице - PullRequest
4 голосов
/ 25 октября 2008

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

Group:
  Group_1:
    name: Atlantic Records
  Group_2:
    name: Capital Records
  Group_3:
    name: Gnarls Barkley
  Group_4:
    name: Death Cab For Cutie
  Group_5:
    name: Coldplay
  Group_6:
    name: Management Company

Группа Coldplay могла быть дочерью группы Capital Records и дочерней компанией группы управления, а Гнарл Баркли мог быть только дочерью Atlantic Records.

Как лучше всего представлять эти отношения. Я использую PHP и MySQL. Также я использую PHP-Doctrine в качестве ORM, если это поможет.

Я думал, что мне нужно будет создать таблицу ссылок с именем group_groups, которая будет иметь 2 столбца. Owner_id и group_id. Однако я не уверен, что это лучший способ сделать это.

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

Ответы [ 8 ]

7 голосов
/ 25 октября 2008

Есть несколько возможных проблем с этим подходом, но с минимальным пониманием требований, здесь идет:

Здесь, похоже, действительно три «сущности»: Artist / Band, Label / Recording Co. и Management Co.

Артисты / группы могут иметь лейбл / запись CO Артисты / группы могут иметь Management Co.

Label / Recording Co может иметь несколько исполнителей / групп

Management Co может иметь несколько исполнителей / групп

Таким образом, между Recording Co и артистами и между Management Co и артистами существуют отношения один ко многим.

Запишите каждую сущность только один раз в своей таблице с уникальным идентификатором.

Поместите ключ «один» в каждом экземпляре «много» - в этом случае Artist / Band будет иметь как Recording Co ID, так и Management Co ID

Тогда ваш запрос в конечном итоге присоединится к Artist, Recording Co и Management Co.

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

3 голосов
/ 25 октября 2008

Пара вариантов:

Самый простой: если у каждой группы может быть только один родитель, то вам просто нужно поле «ParentID» в основной таблице.

Если отношения могут быть более сложными, тогда да, вам понадобится какая-то таблица ссылок. Может быть, даже столбец «тип отношения», чтобы определить, что вид отношения между двумя группами.

1 голос
/ 25 октября 2008

В этом конкретном случае вам было бы целесообразно последовать совету Кена Г., поскольку действительно кажется, что вы моделируете три отдельных объекта в одной таблице.

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

В этом случае у вас действительно будет «связующая» или ассоциативная таблица или таблица брака для управления этими отношениями.

0 голосов
/ 12 декабря 2008

Я думаю, что лучше всего использовать NestedSet http://www.doctrine -project.org / документация / ручной / 1_0 / о / иерархический-данные # вложенный-набор

Просто установите actAs NestedSet

0 голосов
/ 25 октября 2008

Похоже, что это сочетание STI (наследование одной таблицы) и вложенных множеств / древовидных структур. Вложенный набор / деревья являются одним родителем для нескольких детей:

http://jgeewax.wordpress.com/2006/07/18/hierarchical-data-side-note/

http://www.dbmsmag.com/9603d06.html

http://www.sitepoint.com/article/hierarchical-data-database

0 голосов
/ 25 октября 2008

Я согласен с Ken G и JohnMcG в том, что вы должны отделить Management and Labels. Однако они могут забыть, что группа может иметь несколько менеджеров и / или несколько менеджеров в течение определенного периода времени. В этом случае вам понадобятся отношения многие ко многим.

  • управление имеет много полос
  • группа имеет много управления
  • этикетка имеет много полос
  • группа имеет много меток

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

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

0 голосов
/ 25 октября 2008

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

Вы можете добавить столбец с именем parent_id (разрешить пустые значения) и сохранить в нем идентификатор родительской группы. Затем вы можете присоединиться, используя sql, например: «Выберите a. , b. из группы родительской группы присоединения дочерний на parent.id = child.parent_id».

Я рекомендую использовать отдельную таблицу для этой ссылки, потому что: 1. Вы не можете поддерживать нескольких родителей с полем. Вы должны использовать отдельную таблицу. 2. Импортировать / экспортировать / удалить намного сложнее с полем в таблице, потому что вы можете столкнуться с ключевыми конфликтами. Например, если вы пытаетесь импортировать данные, вам необходимо убедиться, что вы сначала импортировали родителей, а затем детей. С отдельной таблицей вы можете импортировать все группы, а затем все отношения, не беспокоясь о фактическом порядке данных.

0 голосов
/ 25 октября 2008

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

...