2017-02-07 19 views
0

У меня есть база данных песен, состоящая из полей, таких как название песни, исполнителя, лириста. Некоторое время в песне может быть несколько исполнителей или несколько лиристов.Идеальный способ разделить несколько полей значений на строки в базе данных?

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

song table 

song_id | title | date 
    1   abc | 2017 

song-artist table 

song_id | artist 
    1   John 
    1   Joe 

Но с этой установкой он чувствует, как вся моя таблица песня разрозненны. Есть ли более красивый способ разделить их?

+0

Это зависит от многого. Ваша таблица «песен» читается или записывается? Как его спрашивают? – Johnsyweb

+0

Вы хотите поместить всю информацию о песне в один стол? Вы в порядке с большой таблицей и наличием в ней данных redudant? Каков ваш план обработки таких изменений, как изменение названия песни или изменение имени исполнителя? –

+0

@ChetanRanpariya С текущей настройкой изменение имени исполнителя уже может быть проблематичным. –

ответ

1

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

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?

+0

Спасибо за объяснение, я думаю, что я буду придерживаться настройки 1, чтобы остаться с правилами, а так как мой хост-провайдер не находится на MySQL 5.7. – reddy

+0

ok У меня появилось больше вопросов при расщеплении значений. Песня будет иметь «группы», будучи исполнителем певца, а также отдельными исполнителями. Поэтому я создал таблицу «group» с 'group_id',' group_name', 'person_id', а таблица« song_artist »будет иметь' song_id' 'person_id' и' group_id', причем один из последних 2 равен NULL в зависимости от данных песни. Это нормально? Или я должен еще разделить их на 2 таблицы «song_artist» и «song_artist_group»? – reddy

+0

Не совсем. Вам нужно сначала определить четкую формулировку того, что вы хотите хранить в базе данных. Вы хотите знать, кто когда-либо участвовал в любой песне из группы A? или вы также хотите знать, кто является основным компонентом каждой группы? А затем проанализируйте связь между группой и другими вовлеченными субъектами. В качестве ответа можно ответом 'SETUP 1.1' в моем ответе. –

 Смежные вопросы

  • Нет связанных вопросов^_^