Вопрос проектирования базы данных «многие ко многим» - PullRequest
4 голосов
/ 06 февраля 2010

Скажем, у вас есть следующее табличное отношение "многие ко многим":

user
-----
id
first_name
last_name

user_prefs
----------------
id
preference_name

user2user_prefs
-------------
id
user_id
user_pref_id

Но, скажем, у вас есть пользовательские предпочтения "homepage" и вам нужно где-то хранить реальный URL домашней страницы. Куда это пойдет?

Я не могу поместить значение в user_prefs, потому что тогда это значение будет применяться ко всем, у кого есть это отображение.

Я могу поместить его в user2user_prefs примерно так:

user2user_prefs
-------------
id
user_id
user_pref_id
value

Но лучше ли это с точки зрения нормализации? Что-то не совсем правильно в том, как я это делаю (во-первых, я не могу использовать ENUM для нового «значения», потому что оно должно содержать все значения для всех предпочтений). Есть мысли?

Спасибо! Stabby L

Ответы [ 4 ]

3 голосов
/ 06 февраля 2010

Вы должны посмотреть на функциональные зависимости. Значение не зависит от пользователя, оно не зависит от userpref, но оно зависит от обоих. Это подразумевает, что вам нужно поместить его во вкладку user2user_prefs, как вы и предлагали.

Если вам нужно использовать enum, тогда атрибут value может искать значения в другой таблице.

1 голос
/ 06 февраля 2010

Мне кажется, что определенный тип значения на самом деле не относится к отношениям "многие-многие". Если конкретное значение свойства является специфическим для каждого пользователя, то, похоже, это должна быть отдельная таблица. Такое ощущение, что между user и другой таблицей, которая имеет настройки, уникальные для каждого пользователя, будет отношение 1-много.

Редактировать: Для таблицы 1 ко многим:

user_specific_prefs
------
id
user_id
pref_name (or possibly pref_id that indicates the type)
pref_value (store www.myhome.com for example)

user_id - это просто внешний ключ, возвращаемый конкретному пользователю. По сути, это (в логическом смысле) добавление дополнительных столбцов в пользовательскую таблицу. Но, как указывает Андомар, это добавляет сложности. Но если у вас есть огромное количество таких предпочтений, то может быть хорошим. С другой стороны, я видел таблицы с сотнями столбцов. Я не говорю, что это хорошо (и я их не создавал), но они выполняют свою работу и просты в использовании.

1 голос
/ 06 февраля 2010

Я не могу поместить значение в user_prefs потому что тогда то же значение будет относится ко всем, кто имеет это отображение.

Вы слишком нормализуетесь. Домашняя страница будет в порядке в user_prefs.

На самом деле, на вашем месте я бы использовал только одну таблицу:

user
-----
id
first_name
last_name
homepage
<other settings>

Отношения между ключевыми ключами, особенно отношения «многие ко многим», сопряжены со значительными издержками. И работа разработчика программного обеспечения состоит в том, чтобы держать сложность под контролем.

0 голосов
/ 06 февраля 2010

Ты очень близко.

[Редактировать: мой ранее блестящий ответ не был таким блестящим.]

Отредактированные таблицы:

users
-----
id
first_name
last_name
preferences

Поле настроек будет содержать сериализованный объект или массив опций конкретных пользователей. В PHP:

if ( is_array( $options ) || is_object( $options ) )
       serialize( $options );

Руководство по сериализации

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