Нужно назначить несколько атрибутов для записей - я должен выбрать одну таблицу или несколько таблиц? - PullRequest
1 голос
/ 18 декабря 2009

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

Итак, я могу придумать два основных подхода. Интересно, какой подход лучше?

  1. Имеется отдельная таблица для каждого атрибута (например, GENRE, ARTIST). Столбцы в каждой таблице будут: album_id и attr_value.

  2. Имеется одна таблица ATTRIBUTES, которая также будет включать, помимо album_id и значения, имя атрибута ("жанр", "исполнитель", ...).

Обычно я выбираю метод 1 (реляционная БД и все такое), но если я выберу метод 2, я думаю, что когда я хочу добавить новый атрибут, мне не нужно создавать новую модель, контроллер и просмотр.

Есть мнения?

Ответы [ 5 ]

2 голосов
/ 18 декабря 2009

Это не столько проблема MVC, сколько вопрос нормализации.

Существует процесс нормализации вашей базы данных и установления сущностей (таблиц). Двумя типичными формами являются 3-я нормальная форма или нормальная форма Бойса-Кодда. Поиск любого из них должен предоставить достаточно информации. Теперь, когда сказано, что есть несколько других проектов, которые вы можете использовать, кроме стандартной нормализации. Все зависит от того, как вы хотите сбалансировать ошибки (обновление / вставка) и производительность. Многие люди выступают за нереляционные схемы (nosql, couchdb и люди, которые считают, что старые опасения по поводу коррупции из-за пустых столбцов сегодня не нужны). Тогда есть реальность, что сериализованные массивы открывают возможность гибридного дизайна. Вы, кажется, больше обсуждаете EAV (значение атрибута сущности) против дополнительной таблицы. EAV имеет репутацию более медленного дизайна, но он действительно полезен, когда единицы ввода не будут известны заранее. Так что с EAV, если у меня есть художник и я хочу добавить родной город «столбец», мне не нужно создавать новую таблицу столбцов, просто новую запись в таблице атрибутов. Также известно, что EAV сложно проверить и напечатать.

В своих продуктах я играю безопасно и отношусь к делу (форма Бойса-Кодда) Да, это означает больше моделей и больше отношений, но это стоит нескольких дополнительных часов. Кроме того, в MVC-фреймворках, таких как Cakephp, создавать модели было гораздо проще. Каждый раз, когда я использовал EAV, мне хотелось, чтобы я просто больше времени уделял планированию.

1 голос
/ 18 декабря 2009

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

Должен быть довольно статичный набор атрибутов для статических таблиц.

0 голосов
/ 21 декабря 2009

Вы должны сделать это с помощью 3-й нормальной формы

В CakePHP корабли отношений, которые вы ищете, и обязательные поля:

<?php
    class Album etends AppModel
    {
        public $name = "Album";
        public $hasAndBelongsToMany = array( 'Artist', 'Genre' );
    }
?>
<?php
    class Artist extends AppModel
    {
        public $name = "Artist";
        public $hasAndBelongsToMany = array( 'Album' );
    }
?>
<?php
    class Genre extends AppModel
    {
        public $name = "Genre";
        public $hasAndBelongsToMany = array( 'Album' );
    }
?>

// fields for the tables with their table names
// only the required ones for the relationships rest is up to you
artists
    --id

albums
    --id

genres
    --id

albums_artists
    --id
    --album_id
    --artist_id

albums_genres
    --id
    --album_id
    --genre_id

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

0 голосов
/ 18 декабря 2009

Я бы отнес Альбом и Жанр как две разные модели. Затем вы можете создать таблицы для каждого атрибута / модели в дополнение к другой таблице, отображающей отношения между ними. Структура базы данных будет выглядеть примерно так:

=====
Table: Albums
-- id
-- name
-- artist

====
Table: Genres
-- id
-- name

====
Table: Album_Genres
-- id
-- album_id
-- genre_id

Просто добавьте все свои альбомы и жанры в соответствующую таблицу, чтобы указать, что альбом принадлежит определенному жанру, и создайте новую строку в таблице Album_Genres. Если вам необходимо добавить / удалить какие-либо атрибуты в будущем, это так же просто, как создать / удалить пару таблиц.

0 голосов
/ 18 декабря 2009

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

При этом мы оба согласны использовать вашу идею № 1 - но теперь вы хотите иметь возможность добавлять новые атрибуты. Обычно это проще всего сделать с помощью «мета» таблицы - таблицы, которая абстрагирует фактические отношения объекта и его атрибутов - давая вам то, что вы хотите - динамические атрибуты.

Это может выглядеть так

=======================
Table Name: Albums
----------------AlbumID
----------------GenreID --> foriegn key --> Genre in Genre Table
----------------ArtistID --> foriegn key --> Artist in Artist Table
----------------Name
----------------Etc (attributes that you know you will need)
=======================
Table Name: AlbumMeta
----------------AlbumID
----------------Key
----------------Value
=======================

Теперь - ваши альбомы могут иметь конкретные атрибуты (т. Е. Атрибуты, которые есть у всех альбомов), и если появляются новые бизнес-правила, скажем, только для инди-альбомов, - у вас есть ссылка на ваш новый партнерский сайт "indiealbums.com" - вы может создать запись AlbumMeta для каждого альбома в жанре инди ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...