Таблица с множеством атрибутов - PullRequest
5 голосов
/ 18 марта 2010

Я планирую построить какой-нибудь проект базы данных.

Одна из таблиц имеет много атрибутов.

Мой вопрос: что лучше, разделить класс на 2отдельные таблицы или положить их все в одну таблицу.ниже приведен пример

create table User { id, name, surname,... show_name, show_photos, ...)

или

create table User { id, name, surname,... )
create table UserPrivacy {usr_id,  show_name, show_photos, ...)

Производительность, которую я предполагаю, аналогична, поскольку я могу использовать индекс.

Ответы [ 7 ]

4 голосов
/ 18 марта 2010

Лучше всего поместить все атрибуты в одну таблицу.

Если вы начинаете хранить имена атрибутов в таблице, вы сохраняете метаданные в своей базе данных, что нарушает первую нормальную форму.

Кроме того, хранение их в одной таблице упрощает ваши запросы.

Вы бы предпочли:

SELECT show_photos FROM User WHERE user_id = 1

Или

SELECT up.show_photos FROM User u
LEFT JOIN UserPrivacy up USING(user_id)
WHERE u.user_id = 1

Соединения в порядке, но сохраняют их для связывания отдельных сущностей и отношений 1-> N.

Существует ограничение на количество столбцов, и только если вы думаете, что можете достичь этого предела, вы сделаете что-нибудь еще.

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

Также обратите внимание, что в поле id пользователя должно быть имя_пользователя, а не просто идентификатор, если только вы не используете Ruby, который заставляет просто идентификатор. 'user_id' предпочтительнее, потому что при использовании только id ваши объединения выглядят так:

ON u.id = up.user_id

Что кажется странным, и предпочтительный способ таков:

ON u.user_id = up.user_id

или более просто:

USING(user_id)

Не бойтесь «добавить еще один атрибут». Это нормально и нормально.

2 голосов
/ 18 марта 2010

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

Вам не нужно 'show_photos', чтобы описать пользователя, но вам нужно это, чтобы описать UserPrivacy.

0 голосов
/ 04 июля 2010

Если некоторые столбцы имеют значение (не identifiable or dependent на primary key) или (используются значения из набора definite/fixed repeatedly) таблицы, создайте другую таблицу для этих столбцов и ведите один к одному отношения.

0 голосов
/ 18 марта 2010

Так как это, кажется, отношение один к одному, я бы обычно держал все это в одной таблице, если:

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

Или, если вы обычно будете запрашивать основную таблицу отдельно и вам не понадобятся эти поля большую часть времени.

0 голосов
/ 18 марта 2010

Почему бы не иметь таблицу пользователей и таблицу функций, например ::100100

create table User ( id int primary key, name varchar(255) ... )</p> <p>create table Features ( user_id int, feature varchar(50), enabled bit, primary key (user_id, feature) )

Тогда данные в вашей таблице характеристик будут выглядеть так:

 | user_id | feature     | enabled
 | -------------------------------
 | 291     | show_photos | 1
 | -------------------------------
 | 291     | show_name   | 1
 | -------------------------------
 | 292     | show_photos | 0
 | -------------------------------
 | 293     | show_name   | 0
0 голосов
/ 18 марта 2010

Вам следует подумать о разделении таблицы, если все атрибуты конфиденциальности обнуляются и, скорее всего, будут иметь значения NULL.

Это поможет вам уменьшить основной стол.

Если атрибуты конфиденциальности будут в основном заполнены, разделять таблицу нет смысла, так как для извлечения данных потребуются дополнительные JOIN с.

0 голосов
/ 18 марта 2010

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

TABLE Attribute
(
    ID
    Name
)
TABLE User
(
    ID
    ...
)
TABLE UserAttributes
(
    UserID FK Users.ID
    Attribute FK Attributes.ID
    Value...
)

Хорошие комментарии от всех. Я должен был быть более ясным в своем ответе.

Мы делаем это совсем немного, чтобы обрабатывать особые случаи, когда клиенты просят нас каким-то образом адаптировать наш сайт для них. Мы никогда не «складываем» NVP в столбцы в запросе - мы всегда спрашиваем: «Должен ли я сделать это здесь?» ища определенный атрибут, указанный для клиента. Если это там, это «правда». Таким образом, вместо того, чтобы иметь тонну булевых столбцов, большинство из которых были бы ложными или равными NULL для большинства клиентов, и тенденция к увеличению числа этих функций, для нас это хорошо работает.

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