ФорумПрограммированиеPHP для идиотов → Хранение параметров пользователей

Хранение параметров пользователей

  • vasa_c

    Сообщения: 3131 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 17:13

    Предлагаю обсудить варианты по хранению данных пользователей.
    Итак, в системе зарегистрированны пользователи, и у них есть параметры:
    основные — логин, пароль, уникальный идентификатор, возможно, мыло. Без них, как понятно, никуда. Хранятся они обычно в одной таблице.
    дополнительные — асько, васько, пол, дата рождения…

    Как хранить дополнительные? Несколько вариантов:


    Вариант номер раз

    В той же таблице, в одной строке с основными.
    Плюсы очевидны: нет лишних таблиц, запросы проще и быстрее, на отдельный столбец можно поставить различные типы и индексы.

    Минусы: офигенно длинная таблица, жесткий набор параметров.
    Например, у форумов куча столбцов - AIM, YIM, IRC… Из тысяч пользователей, дай бог, двое эти поля заполнят. Захотим добавить новый параметр — лезем в базу.
    Для форумов, это возможно еще и ничего, но если делаем более/менее универсальную систему, данный вариант практически нерабочий.


    Вариант номер два

    Таблица со списком параметров:
    1. Идентификатор
    2. Название (мыло, аська…)
    3. Другая фигня

    Таблица привязки параметров к пользователям:
    1. Ид.юзера
    2. Ид.параметра
    3. Значение параметра

    Плюсы - набор легко расширять. Причем может расширять редактор из админки.
    Минусы - менее эффективная выборка. Числовые значения приходится хранить в строках. И т.п.

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


    Вариант номер три

    Одна дополнительная связанная таблица:
    1. Ид.юзера
    2. Имя параметра
    3. Значение параметра

    Для повышения эффективности, конечно, можно сделать доп.таблицу, в которой бы автоматически кешировались имена, а в самой таблице были только их id. Но с точки зрения интерфейса, доступ к параметрам производился просто, примерно так:

    setUserParam(10, 'email', '[email protected]'); // Установили значение параметра для 10-го юзера
    getUserParam(11, 'email'); // Получили мыло 11-го пользователя


    Плюсы: полная свобода, граничащая с анархией. Ставим какие хотим параметры и где хотим.
    Минусы, по сравнению со вторым: отрисовывать и обрабатывать стандартные фишки, типа профилей или формы регистрации придется вручную. Но зато гораздо большая свобода выбора при этом. И это ничем не будет отличаться от пункта 2.


    Доп.данные

    Кроме вышеописанных "профильных" параметров, может существовать еще большое количество, связанных с каждым конкретным пользователем, данных. Какие-либо настройки интерфейса. Например, показываем таблицу, человек щелкнул по шапке, упорядочил по какому-то одному столбцу, ушел с сайта, вернулся, а состояние запомнилось, мелочь, а приятно :). При использовании варианта номер три, данные параметры можно объеденить с парамерами пользователя.


    Как вы подобные вещи решаете? Какие мысли?
  • Patrick

    Сообщения: 506 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 17:36, спустя 23 минуты 14 секунд

    Я за второй вариант….
    А вообще всё зависит от задачи, если требуется расширяемость, то 2, если нет то 1…

  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 17:53, спустя 16 минут 42 секунды

    Ну можно и в первом варианте сделать динамические хактеристики через ALTER TABLE. Обычно еще при этом возникает служебная таблица в которой хранится перечень полей. Чую ща полетят ссаные тряпки … :)
  • speedleader

    Сообщения: 28 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 18:07, спустя 14 минут 15 секунд

    "Вы что, е..анулись?" (с) заяц ПЦ.
    Ни в коем случае не менять структуру таблиц!

    Поддерживаю второй вариант….Если мне не изменяет память универской теории (хотя возможно и изменяет), это – третья нормальная форма, и это – самый тазик для СУБД. )


    Минусы - менее эффективная выборка. Числовые значения приходится хранить в строках. И т.п.


    А здесь и во втором и в третьем придется хранить числовые значения в строковых….имхо это небольшой проигрыш, по сравнению с выигрышем от выноса в отдельную таблицу.

    В третьем же варианте будет проигрыш - постоянно будут повторяться имена параметров одинаковые => лишние данные, избыточность.
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 18:32, спустя 24 минуты 48 секунд


    "Вы что, е..анулись?" (с) заяц ПЦ.
    Ни в коем случае не менять структуру таблиц!


    А существует внятное объяснение "почему нельзя"?

    третья нормальная форма, и это – самый тазик для СУБД. )


    В случаях высоких нагрузок денормализация совершенно естественный и даже более того, совершенно необходимый процесс. Не зацикливайтесь на стереотипах.
  • speedleader

    Сообщения: 28 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 18:47, спустя 15 минут 20 секунд



    "Вы что, е..анулись?" (с) заяц ПЦ.
    Ни в коем случае не менять структуру таблиц!


    А существует внятное объяснение "почему нельзя"?

    Простите, не задумывался над этим. Опять университетский стереотип? )
  • Patrick

    Сообщения: 506 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 18:49, спустя 1 минуту 45 секунд

    А существует внятное объяснение \"почему нельзя\"?

    а где ты видел что бы менялась БД???? + это будет адд по прошествии нескольких месяцев, активных изменений…
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 19:02, спустя 13 минут 9 секунд


    это будет адд по прошествии нескольких месяцев, активных изменений…


    Да почему? Она же не хаотично меняется, а по определенным законам.
    Ну допустим в первом варианте раз в полгода у пользователя появляется новая характеристика, какая-нибудь новомодная "васько" в добавок к стандартной "асько" :). У самого главного админа есть панель с кнопкой "добавить характеристику", которая добавляет этот столбец. Не вижу предпосылок для ада.

    Не, я прошу, не понять меня неправильно. Я абсолютно не пропагандирую этот подход. Я абсолютно согласен с твоим первым утверждением, что "все зависит от задачи". Всего навсего я хотел сказать, что ИМХО, задача и условия могут быть такие, что пригодится и этот вариант.

  • Dagdamor

    Сообщения: 47 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 19:58, спустя 56 минут 6 секунд

    AlexB, +1. Первый вариант однозначно.
    Держать дополнительную таблицу с отношением "один-ко-многим" там, где можно обойтись одной таблицей - изврат.
    Делать выборку кучи записей там, где можно обойтись одной простой выборкой по первичному ключу - изврат.
    Использовать один и тот же тип поля для разнотипных значений - ну в общем вы меня поняли ;) и так далее.

    В динамическом изменении структуры таблицы нет ничего страшного и ужасного. Другое дело, если вы пользуетесь ORM, это может привести ваши классы в ступор ;) но это уже ваши проблемы.
  • Dagdamor

    Сообщения: 47 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 20:03, спустя 4 минуты 58 секунд

    а где ты видел что бы менялась БД???? + это будет адд по прошествии нескольких месяцев, активных изменений…

    А во что превратится такая "вспомогательная" таблица через несколько месяцев активных изменений? В помойку. А ведь найти и исправить в ней какие-либо ошибки будет гораздо сложнее, чем сделать то же самое для списка полей одной таблицы.
  • vasa_c

    Сообщения: 3131 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 20:50, спустя 46 минут 37 секунд

    Ладно, добавление новых параметров не слишком частое действие и можно обойтись ALTERом. А насколько здорово по вашему иметь таблицу на тысячу столбцов из которых большинство заполнено только у единиц?
  • Dagdamor

    Сообщения: 47 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 21:04, спустя 13 минут 49 секунд

    Для начала, никто из пользователей никогда не станет заполнять профайл в 1000 полей. Если в системе такое количество параметров, значит у заказчика с головой не все в порядке ;) даже если предположить, что у нас всего 100 полей, все равно, делать для каждого юзверя выборку, которая может вернуть до 100 записей, только чтобы узнать его профайл - тоже не очень здорово. И где хранить информацию об этих полях, если они хранятся только для непустых значений? Еще одну таблицу городить?

    Если волнует проблема свободного места на диске, то не забывайте, что пустые значения в MySQL (NULL, либо 0/пустая строка, если поле NOT NULL) не хранятся физически и не занимают места. Затраты на хранение значения не в виде поля, а в виде отдельной записи приведут к гораздо большей трате места.
  • vasa_c

    Сообщения: 3131 Репутация: N Группа: в ухо

    Spritz 10 октября 2007 г. 21:07, спустя 3 минуты 34 секунды

    Какого заказчика? Здесь нет никаких заказчиков :)
    А только ли "профильные" параметры (мыло, ФИО и т.п.) являются данными, которые следует привязывать к пользователю?
  • Dagdamor

    Сообщения: 47 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 21:44, спустя 36 минут 27 секунд

    Судя по первому сообщению в теме, речь идет именно о таких параметрах.
  • speedleader

    Сообщения: 28 Репутация: N Группа: Кто попало

    Spritz 10 октября 2007 г. 22:11, спустя 27 минут 10 секунд


    Для начала, никто из пользователей никогда не станет заполнять профайл в 1000 полей.


    Не забывайте, существуют параметры, заполняемые автоматически. От этого они не перестают быть параметрами пользователя.


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


    Например, мне нужно знать и хранить где-то данные о том, какие темы в данном форуме юзер прочитал, а какие - нет. Это тоже параметр, зависимый от пользователя. Было бы глупо для каждой новой созданной темы менять таблицу пользователей ALTER-ом. Опять мы приходим к мнению, то что реализация должна быть прежде всего адекватна задаче - и только тогда она может быть названа лучшей.

Пожалуйста, авторизуйтесь, чтобы написать комментарий!