2009-05-10 6 views
0

Я пытаюсь смоделировать художников и песни, и у меня есть проблема, когда у меня есть Song_Performance может быть исполнено многими художниками (например, дуэтом), поэтому у меня есть Artist_Group, чтобы представлять, с кем песни исполняются.Как вы разрешаете объект коллекции многих ко многим в СУБД?

Ну, теперь у меня есть отношения «много-ко-многим» между Artist и Artist_Group, где Artist_Group уникально идентифицируется коллекцией художников в этой группе. Я могу создать объект пересечения, представляющий участие исполнителя в Artist_Group (Artist_Group_Participation?)

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

В книге «Моделирование моделирования данных» Джона Карлиса и Джозефа Магуара упоминается эта форма и упоминается в ней как «много-многообразна сущность» и говорится, что она очень редка, но не указывает, как ее разрешить так как очевидно, что отношения «многие ко многим» не могут храниться непосредственно в СУБД. Как мне это представить?

Edit:

Похоже, все это указывает таблицу пересечения, но это не моя проблема. У меня есть это. Моя проблема связана с тем, что вы не можете добавить запись Artist_Group, где группа исполнителей, которые она содержит, совпадает с существующей группой, игнорируя порядок. Я думал о том, что идентификатор для Artist_Group - это varchar, который является конкатенацией различных исполнителей, которые его составляют, что позволило бы решить проблему, если бы имел значение заказ, но наличие Artist_Group для «Elton John and Billy Joel» не мешает добавлению группы для «Билли Джоэла и Элтона Джона».

+0

В качестве предположения вы можете захотеть изменить заголовок, чтобы он четко указывал на то, что ваша проблема заключается в том, чтобы * обеспечить уникальность комбинаций * ассоциаций в отношениях «многие-ко-многим», а не сопоставлять многие -Много отношения как такового. Это может помочь читателям «внимательно прочитать вопрос». – itowlson

ответ

1

Я думаю, что мне не хватает точки отношения «Artist_Group».

модель данных в моей голове есть:

Исполнитель: физическое лицо.

Песня: сама песня.

Спектакль: Особое исполнение или композиция песни. Обычно у нее будет одна песня, но вы можете предоставить таблицу ссылок m: n, чтобы разместить смесь. В идеале это была бы одна реальная производительность, то есть была бы связанная дата.

Запись: конкретная фиксированная версия исполнения (компакт-диск или что-то еще). Обычно у Performance есть только одна запись, но с отдельной таблицей будет обрабатываться сценарий Grateful Dead/multiple-bootleg, а также переиздание альбомов, воспроизведение радио по сравнению с версиями live или CD и т. Д.

Performance_Artists: Соединительный стол от конкретного исполнения до списка исполнителей. Для каждого из них также может быть атрибут, который описывает их роль (роли) в производительности (вокалист, барабанщик и т. Д.).

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

Если вы пытаетесь представлять явное отношения между множеством художников (то есть, они находятся в одной и той же группы), ну, группы имеют имена, которые имеют уникальность (хотя и не достаточно, чтобы быть первичным ключом) , и группа может быть сохранена просто как Исполнитель, а затем иметь таблицу ссылок Artist_Member, которая ссылается на отдельные записи исполнителя. Или у вас может быть отдельная таблица Band и таблица Band_Members, чтобы назначить ей исполнителей, возможно, с датами членства. В любом случае, просто помните, что участники группы меняются со временем, а роли группы меняются от одной песни к другой, поэтому объединение группы с исполнением не должно заменять привязку выступлений непосредственно к участвующим артистам.

+0

Хм .... У меня было то, что ты сказал раньше, но я перечеркнул его, потому что я нашел проблему с ним, но я не могу вспомнить, что это было. Может быть, это было просто мое воображение ... +1 в любом случае, и если я не могу придумать причину, по которой я первоначально отверг это решение, тогда я соглашусь. – Davy8

1

Первичным ключом для Artist и Artist_Group будет числовой, инкрементный идентификатор. Тогда у вас будет таблица Artist_Group_Participation, которая имеет два столбца: artist_id и group_id. Это будут внешние ключи, которые относятся к идентификатору их соответствующих таблиц. Затем, чтобы выбрать все, что вы использовали бы JOIN.

EDIT: Извините, я неправильно понял ваш вопрос. Единственный другой способ, о котором я могу думать, - добавить столбец «художники» в таблицу Artist_Group, содержащую сериализованный массив (при условии, что вы используете PHP, но другие языки имеют эквиваленты) художников и их идентификаторов. Затем просто добавьте ограничение UNIQUE в столбец.

+0

Но инкрементный идентификатор для Artist_Group не применяется, и Artist_Group уникально идентифицируется набором исполнителей в этой группе. Было бы возможно создать вторую Artist_Group с теми же членами (порядок не имеет значения), который просто создал бы другой экземпляр Artist_Group с другим идентификатором, но с теми же членами. Я понимаю, как разбить отношения «многие-ко-многим», когда каждый член отношения имеет независимый идентификатор. Проблема здесь в том, что идентификатор состоит из комбинации от 1 до n разных исполнителей. – Davy8

+0

@musicfreak: вы должны убедиться, что сериализованный массив отсортирован, иначе вы могли бы получить (10,20) и (20,10), которые должны быть тем же самым списком. Кроме того, это связано с обычными проблемами, которые имеет сериализованный массив, например. как долго вам нужна строка? –

+0

@Bill Karwin: Да, это правда, я забыл упомянуть об этом. Я не думаю, что длина - это проблема. Я имею в виду, сколько людей может иметь группа? Семь не более? В зависимости от языка, который вы используете, вы могли бы поместить его в VARCHAR (255). –

1

Вы можете сделать идентификатор каждого исполнителя соответствующим бит в битовом поле. Итак, если Элтон Джон - ID 12, а Билли Джоэл - ID 123, то «группа», образованная дуэтом между Элтоном Джоном и Билли Джоэлем, - Artist_Group ID 10633823966279326983230456482242760704 (т. Е. Имеет 12-й и 123-й бит).

Вы можете применить соотношение, используя таблицу пересечений. Например, используя CHECK ограничение в PostgreSQL:

CREATE TABLE Artist_Group_Participation (
    artist_id int not null, 
    artist_group_id int not null, 
    PRIMARY KEY (artist_id, artist_group_id), 
    FOREIGN KEY (artist_id) REFERENCES Artists (artist_id), 
    FOREIGN KEY (artist_group_id) REFERENCES Artist_Group (artist_group_id), 
    CHECK (B'1'<<artist_id & artist_group_id <> 0) 
); 

Следует признать, что это обходное. Это имеет дополнительное значение для суррогатного ключа Artist_Group, когда суррогатные ключи должны быть уникальными, но не содержать информации.

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

+1

Но что происходит, когда вы получаете 1000 художников? –

+0

Не могли бы вы объяснить это чуть больше? То, как я понимаю, заключается в том, что установка 12-го и 123-го разрядов будет эквивалентом 2^12 + 2^123, который не является числом, с которым вы столкнулись (calc говорит, что это> 10^37, что больше чем даже bigint), поэтому, очевидно, я понимаю это неправильно. – Davy8

+0

@musicfreak: Да, я признаю, что это может стать громоздким. –

0

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

Группа: 3,2,6 -> 2-3-6 и 6,3,2 -> 2-3-6

0

У меня нет большого опыта работы в СУБД. Тем не менее, я прочитал статьи Codd и книги C.J. Date. (! По крайней мере, для меня)

Таким образом, вместо того, чтобы использовать RDBMS жаргон, я постараюсь объяснить более общие термины

бы бессмысленно

Здесь идет -

  1. имена Singer должны быть стандартными на «Имя - Фамилия» основа

  2. Каждый «Singer» должен иметь запись в таблице «Художники группы», даже если они выполняются соло

  3. Каждая запись в группе «Артисты» будет состоять из нескольких «Певиц», упорядоченных по алфавиту. Должна быть единая встреча определенной комбинации.

  4. Каждая песня будет иметь запись уникальной записи из «Группы художников» независимо от того, являются ли они соло, дуэты или в банде.

Я не знаю, имеет ли это смысл, но это мои два цента!