Но с этой настройкой кажется, что весь мой столовый стол был несвязан. Есть ли более красивый способ разделить их?
Pretty - очень субъективный термин.
НАСТРОЙКИ 1
С точки зрения традиционной базы данных реляционной модели, то «симпатичнее» настройки для N: отношения M такие, как это было бы нормализованы один, например:
SONG (id, title, date)
PERSON (id, name)
SONG_ARTIST (song, person)
SONG_LYRICIST (song, person)
Пример:
SONG
ID | title | date
1 | abc | 2017
PERSON
ID | name
1 | John
2 | Mary
SONG_ARTIST
SONG | person
1 | 1
1 | 2
SONG_LYRICIST
SONG | person
1 | 1
Это традиционная установка для N: M отношения, что снижает 1) размер, требуемый для хранения данные, 2) риски избыточности и 3) упрощают обеспечение ссылочной целостности.
1) Если художник Джон пишет много песен, в вашей настройке вы набираете Джона столько раз. Эта ячейка поля является строковым полем. Это действительно зависит от длины поля, но обычно для строкового поля требуется больше байтов на диске, чем целое число, поэтому для повторения текстовых полей обычно требуется больше дискового пространства, чем повторение целочисленных полей.
2) Один из рисков избыточности связан с вводом данных. Если вам нужно вводить строку много раз, в какой-то момент вы можете опечатать ее и, таким образом, создать «нового» исполнителя. Другой риск связан с обслуживанием данных. Скажем, например, вы понимаете, что неправильно набрали имя исполнителя. Этот художник написал 10 песен, и его/ее имя появляется 10 раз в вашей базе данных. Вам придется изменить его 10 раз, и в большинстве случаев эту работу нужно будет выполнять вручную (больше времени и рисков).
С традиционной реляционной установкой вы набираете имя художника только один раз. Если вы ошиблись, это будет неправильно написано везде, но если вы измените его, оно автоматически изменится для всех из них.
3) жесткая структура имеет свои трудности, но связь между 1 человеком и его/ее песнями не подвержена интерпретациям. Возможно, это было введено неправильно, но нет никаких сомнений в том, какие песни написал какой художник. Система даже сможет отличить двух художников по имени.Благодаря этому вы можете применять правила для обеспечения ссылочной целостности (например, «удалить в SONG_ARTIST любую ссылку на конкретное лицо при удалении из таблицы PERSON»)
Даже если вы говорите, что можете жить с изменениями имени, Я настоятельно рекомендую вам иметь людей в своем собственном столе и ссылаться на них, когда их связывают с песнями.
НАСТРОЙКА 1,1
Из приведенного выше примера, если вы хотите добавить информацию, например, о группах/групп (или любой другой информации) первое, что вам нужно сделать, это проанализировать взаимосвязь между этой организацией и любой другой объект в вашей базе данных.
Предполагая начальное базовое определение таблицы ПОЛОСЫ, такие как это:
BAND
ID | title
1 | TheBand
Давайте начнем с самой простой части:
- ПЕСНЮ. 1 песня относится к 1 группе, но в 1 группе может быть много песен (1: N)
Чтобы связать группу со своими песнями (1: N), нам нужно только добавить band_id в качестве внешнего ключа в таблице песня.
SONG
ID | title | date | band
1 | abc | 2017 | 1
Только сделав это, вы сможете перечислить все песни из группы.
SELECT song.id, song.title FROM song, band
WHERE song.band=band.id AND band.id = 1
И, так как мы знаем, музыкант для каждой песни, мы также можем перечислить все музыкант или лирик, участвующие в группе.
SELECT person.id, person.name, song.title
FROM song, band, song_artist, person
WHERE song.band=band.id AND song_artist.song=song.id
AND person.id=song_artist.person AND band.id = 1
Вы можете решить, что это все ваше приложение должно знать: «кто когда-либо участвовал в любой песне из группы X».
В противном случае вы можете принять во внимание, что группы часто приглашают других музыкантов играть определенную песню, но они не являются частью группы. Если вы считаете, что ваше приложение должно быть способным различать, кто только сотрудничает в группе и кто принадлежит к основной группе, то вам нужно определить прямую связь между людьми и группой.
- PERSON. 1 человек может быть основным компонентом во многих диапазонах, а 1 полоса может иметь много основных компонентов (N: M).
Как вы знаете, отношение N: M в реляционной модели должно быть реализовано с использованием третьей таблицы, которая объединяет группы и людей, действующих в качестве основных компонентов.
Другая проблема возникает, поскольку основные компоненты конкретной полосы не являются чем-то статическим и могут меняться со временем. Вы можете решить эту проблему, добавив дату начала и дату окончания в таблицу BAND_CORE_COMPONENT, чтобы вы знали, для каждого человека в группе, когда он/она начинал и когда он закончил, и вы можете задать вопросы о базе данных, такие как: «кто был основным компонентом группы X в январе 2012 года?».
BAND
ID | title
1 | TheBand
SONG
ID | title | date | band
1 | abc | 2017 | 1
PERSON
ID | name
1 | John
2 | Mary
SONG_ARTIST
SONG | person
1 | 1
1 | 2
SONG_LYRICIST
SONG | person
1 | 1
BAND_CORE_COMPONENTS
BAND | person | started | ended
1 | 2 | 2010-01-01 | 2016-06-01
1 | 1 | 2012-01-01 | *null*
Вот вы знаете, что Мэри имел обыкновение быть основным компонентом TheBand с начала 2010 до середины 2016 года мы также знаем, Джон вошел позже (в 2012 году) и все еще является частью TheBand.Мы также знаем, что Джон участвовал как лирик и музыкант в песне abc от TheBand и делал это как основной компонент (потому что песня датируется 2017 годом, а Джон в настоящее время остается основным компонентом). В той же песне Мэри участвовала в качестве соавтора, потому что песня датируется 2017 годом, и к тому времени она не была основным компонентом TheBand.
НАСТРОЙКА 2
Это, как говорится, самым популярная и современная реляционная БД система, такие как MySQL или PostgreSQL в их последних версиях, включают некоторые новые тип, которые помогут вам справиться с N: M отношения в по-разному и уменьшить количество таблиц, необходимых в вашей настройке.
Тип JSON (MySQL 5.7.8 и выше, PostgreSQL 9.2 и выше) может использоваться для хранения отношений в таблице SONG.
SONG
ID | title | date | artists
1 | abc | 2017 | {"lyrics": [1], "music": [1,2]}
PERSON
ID | name
1 | John
2 | Mary
Или даже:
SONG
ID | title | date | artists
1 | abc | 2017 | {"lyrics": [1], "music": {"voice": [1], "guitar": [2]}}
PERSON
ID | name
1 | John
2 | Mary
Это имеет те же преимущества, как и другие настройки (уменьшающие резервирование и сохранение ссылочной целостности, не уверен, что об использовании диска), но, кажется, немного легче читать.
Он вводит новый риск для управления: поскольку вы можете видеть поле artists
, вы можете хранить в нем любой JSON, поэтому структура JSON может быть разной в разных строках, и если это произойдет, тогда структурная целостность данных будет быть сломанным, и ваше приложение будет иметь дело с этим.
Следующие примеры сохраняют ту же информацию, но используют совершенно разные структуры JSON.
SONG
ID | title | date | artists
1 | abc | 2017 | {"lyrics": [1], "music": {"voice": [1], "guitar": [2]}}
2 | def | 2016 | {"lyrics": [1], "music": [{"person": 1, "instrument": "voice"}, {"person": 2, "instrument": "guitar"}]}
Больше от типа JSON в MySQL: Native JSON support in MYSQL 5.7 : what are the pros and cons of JSON data type in MYSQL?
Это зависит от многого. Ваша таблица «песен» читается или записывается? Как его спрашивают? – Johnsyweb
Вы хотите поместить всю информацию о песне в один стол? Вы в порядке с большой таблицей и наличием в ней данных redudant? Каков ваш план обработки таких изменений, как изменение названия песни или изменение имени исполнителя? –
@ChetanRanpariya С текущей настройкой изменение имени исполнителя уже может быть проблематичным. –