Выбираете способ хранения профилей пользователей? - PullRequest
7 голосов
/ 10 января 2009

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

Следующие операторы create table не предназначены для того, чтобы быть исполняемыми, а просто предназначены для того, чтобы дать представление о структуре используемых таблиц.

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

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,

    user_email VARCHAR(320),

    user_joined DATATIME,
    user_last_seen DATATIME,

    user_name_first VARCHAR,
    user_name_last VARCHAR,

    user_name_alias VARCHAR,

    user_location_country VARCHAR,
    user_location_region VARCHAR,
    user_location_city VARCHAR

    # ...
);

Очевидно, что это не очень масштабируемо, и добавление дополнительных свойств меня раздражает. Одним из преимуществ является то, что я могу быстро искать пользователей, соответствующих определенному набору свойств. Я немного осмотрелся, и это довольно распространенный подход (например, Wordpress).

Мой второй подход (тот, с которым я сейчас играю) гораздо более масштабируемый, но я немного обеспокоен производительностью:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,

    user_email VARCHAR(320)
);

CREATE TABLE user_profile(
    user_id INT UNSIGNED NOT NULL,

    visibility ENUM('PRIVATE', 'PUBLIC'),

    name VARCHAR,
    value VARCHAR
);

Используя этот подход, каждое использование имеет набор пар ключей-значений, связанных с ним, что делает добавление дополнительных свойств тривиальным, а также загрузку профиля пользователя при входе в систему. Однако я теряю всю информацию о типах, которая была у меня в первом подходе (например, DATETIME теперь сохраняется как отформатированная строка), поэтому некоторые поиски становятся раздражающими. Это дает мне больше контроля над выбором свойств, которые пользователь хочет публично отображать.

Будет ли лучше гибридный подход, позволяющий мне сбалансировать преимущества и недостатки обоих методов? Какой метод использует SO? Есть ли другой подход к этому, о котором я не думал или не пропустил?

Расширение: При гибридном подходе было бы целесообразно также вставить свойства из пользовательской таблицы в таблицу user_profile, чтобы управлять их видимостью для других пользователей, или это может рассматриваться как дополнительные издержки?

Ответы [ 4 ]

4 голосов
/ 10 января 2009

Я бы использовал гибридный подход. Некоторые основные свойства, такие как имя пользователя, адрес электронной почты, lastlogindate и т. Д., Должны быть добавлены в вашу таблицу пользователей. Элементы второстепенной важности могут быть добавлены как пары ключ / значение.

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

3 голосов
/ 10 января 2009

Гибридное решение не очень хорошее. По сути, вы храните дополнительные свойства в таблице пакетов свойств. Это усложнит создание отчетов и запросов в долгосрочной перспективе. Кроме того, хранение дат, int, decimal, ntext и т. Д. В качестве varchar не будет приемлемым обменом производительности для масштабируемости. Как бы вы создали отношения за этим столом, если возникнет такая необходимость?

Лучший подход - иметь пользовательскую таблицу для информации о пользователях. Затем по мере расширения ваших потребностей создайте новые классы, которые представляют новые функции. Эти новые классы, вероятно, будут иметь соответствующие таблицы. Таким образом, ваш «пользовательский» класс не расширяется экспоненциально, когда свойства, связанные с пользователем, принадлежат их собственному пространству. Да, в будущем у вас может появиться новое свойство в пользовательской таблице. В этот момент вам нужно вернуться и настроить схему и DBAL, но это цена кода, которую легко понять.

В вашем примере у вас есть адресная информация для пользователя в первой пользовательской таблице. Я знаю, что мне нужно хранить адреса не только для пользователей. Таким образом, у меня будет отдельная таблица адресов, затем я включу обнуляемый AddressId в таблицу пользователей. Таким образом, когда у меня есть таблица Stores, таблица Events, я также могу включить в нее отношения AddressId. Побочным эффектом этого подхода является то, что когда я возвращаюсь и добавляю lat / long к объекту Address, все в моей модели данных тоже получают эти новые свойства.

0 голосов
/ 10 января 2009

Почему бы не иметь поле XML для хранения дополнительной информации, которая не важна.

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

0 голосов
/ 10 января 2009

Я бы тоже выбрал гибридное решение из соображений производительности и масштабируемости дизайна.

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

...