Планируется несколько однотипных сайтов, имеющих по сути один и тот же функционал. Но в зависимости от конкретной задачи каждого сайта необходимы разные типы регистрационных данных.
Если более понятно, то задача стоит в том, чтобы из админки можно было создать дополнильные типы пользователей, имеющих помимо стандартных полей (логин, пароль, email и т.д.) еще и специализированные, присущие только этому типу пользователей.
Т.е. дословно - на примере форума (все утрировано):
Создаю отдельную категорию пользователей: модераторы.
Создаю для них обязательные и необязательные поля (о себе, город, хобби и т.д.), выпадающие списки, чекбоксы и т.д. (на выбор - любой элемент формы).
И при регистрации этого типа пользователей предлагается заполнить помимо основных (логин, пароль, почта) еще созданные админом поля. И эта информация вносится в БД примерно так:
основная инфа - в общую таблицу пользователей, а вот как поступить с этой динамической частью информации я не могу придумать.
Сложность здесь в том, что кол-во и типов этих дополнительных полей может быть сколько угодно, при этом они могут изменяться, добавляться и удаляться в процессе использования - соответственно создавать динамически для каждого типа пользователя свою таблицу - нереально.
Сейчас в голове крутится одна мысль - создать одну таблицу соответствия форм с их названиями и типами для типа пользователя, а также создать отдельные таблицы на каждый тип поля (textarea, text, checkbox, select, date) со связкой по user_id с каждым конкретным юзером из общей таблицы пользователей, а также по form_id с таблицей форм для данного типа юзеров, и вносить инфу туда. А потом по связкам user_id и form_id из таблиц форм и типов поля доставать инфу о конкретном юзере.
Получается довольно объемная и сложная система. Думаю над ней уже несколько дней.
Может есть какой-то другой способ сохранения динамической информации для пользователей?
Прошу совета, как это можно реализовать по другому? (если это вообще возможно =) )
Спустя 1 час, 33 минуты, 46 секунд (26.12.2008 - 23:24) FatCat написал(а):
В движке этого форума есть дополнительные поля профиля, выносимые в ДВЕ таблицы: одна для названия полей, вторая для значений. Вроде бы структура не очень громоздкая, хотя при отображении дополнительных полей профиля в каждом сообщении под аватаркой нагрузка прирастает ощутимо: порядка 0,005 секунды на каждое сообщение на странице при использовании всего 4 дополнительных полей.
Если не делать отображения в постах, а только в профиле - тормжение в 0,005 секунды добавится только на просмотры профилей.
Если не делать отображения в постах, а только в профиле - тормжение в 0,005 секунды добавится только на просмотры профилей.
Спустя 1 час, 13 минут, 15 секунд (27.12.2008 - 00:37) LDZ написал(а):
Ого... довольно серьезно...
А другие какие-то варианты у кого-нибудь есть?
А другие какие-то варианты у кого-нибудь есть?
Спустя 7 часов, 24 минуты, 56 секунд (27.12.2008 - 08:02) Sylex написал(а):
интересно, а как часто это, в процессе будут поля меняться? ALTER TABLE не сойдет?
Спустя 4 часа, 49 минут, 51 секунда (27.12.2008 - 12:52) LDZ написал(а):
Да вот периодичность неизвестна. Как понадобятся, так и будут меняться.
Поэтому не хотелось бы использовать динамически создаваемые таблицы.
Как вариант - сделать одну таблицу - с названиями форм со связкой на пользователя. И вторую с разными типами колонок - на разный тип информации (чекбокс, textarea и т.д.) - и заполнять согласно связке с таблицей форм только те поля, к какому типу это поле относится. Так мы получим всего 2 таблицы, но во второй в каждой записи будет заполнено по 2-3 поля из примерно 8-10. Что на мой взгляд не совсем рационально
Поэтому не хотелось бы использовать динамически создаваемые таблицы.
Как вариант - сделать одну таблицу - с названиями форм со связкой на пользователя. И вторую с разными типами колонок - на разный тип информации (чекбокс, textarea и т.д.) - и заполнять согласно связке с таблицей форм только те поля, к какому типу это поле относится. Так мы получим всего 2 таблицы, но во второй в каждой записи будет заполнено по 2-3 поля из примерно 8-10. Что на мой взгляд не совсем рационально
Спустя 35 минут, 15 секунд (27.12.2008 - 13:27) FatCat написал(а):
Цитата (Sylex @ 27.12.2008 - 08:02) |
интересно, а как часто это, в процессе будут поля меняться? ALTER TABLE не сойдет? |
Для большинства случаев это будет лучшим решением.
Для информаци, многократно выводимой на странице, добавление новых полей в использующуюся таблицу в разы менее нагрузочно, чем привязка новой таблицы.
Проблема скорее в сложности написания админки, для ALTER TABLE это более сложно.
Спустя 16 минут, 35 секунд (27.12.2008 - 13:44) FatCat написал(а):
Цитата (LDZ @ 27.12.2008 - 12:52) |
Так мы получим всего 2 таблицы, но во второй в каждой записи будет заполнено по 2-3 поля из примерно 8-10. Что на мой взгляд не совсем рационально |
Это-то как раз фигня...
Чтобы в топике рядом с текстом выводилось имя автора, джоиним две таблицы:
SQL |
ibf_posts p left join ibf_members m ... |
Чтобы вывести под аватар дополнительные поля профиля, уже требуются 4 таблицы:
SQL |
ibf_posts p left join ibf_members m ... left join ibf_pfields_data d ... left join ibf_pfields_content c ... |
Для страницы топика из 15 сообщений 15 разных авторов первый запрос "съест" под денвером 0,045 секунды, второй - 0,1 или даже больше.
Добавление полей в ibf_members тоже повлияет на время запрос, но не столь критично на небольших форумах. Степень торможения будет пропорциональна числу записей в таблице мемберов. Чисто эмпирически, таблица мемберов начинает ощутимо тормозить, когда ее размер переваливает за 70-80 Мб; это порядка полумиллиона мемберов в стандартной таблице ibf_members; а добавлениями в нее новых полей Вы просто уменьшите эту цифру. Но до тех пор, пока число мемберов меньше критического, торможения почти не будет.
Спустя 1 час, 22 минуты, 52 секунды (27.12.2008 - 15:06) LDZ написал(а):
Ну так самым оптимальным из всего этого что является?
2 таблицы всего или по таблице на каждый тип поля?
2 таблицы всего или по таблице на каждый тип поля?
Спустя 1 час, 25 минут, 9 секунд (27.12.2008 - 16:32) HardWoman написал(а):
У меня в связи с этой задачей вопрос - не для этих ли целей предназначен тип set в базе данных, столбцы этого типа могут содержать набор определенных значений либо null
Я предполагаю, что хранить в таком типе порядка 1000 значений уже может быть нерационально, но ведь то значений полей не так много - всего десяток.
Так не проще ли в основной таблице юзер добавить столбец - перечень полей, и сохранять перечень полей для каждого пользователя именно в этом типе.
Можно сохранить просто перечень числовых значений - обуславливающих вывод конкретного поля - а сам вывод прописать в php файле.
Я конечно не могу как профи предсказать рациональность такого решения, равно как скорость и нагрузку, потому как мало опыта и знания по большей части теоретические.
В связи с этим прошу профи ответить на вопрос - если такое решение нерационально - то в каких случаях будет рационально использовать тип столбца set и enum.
Кстати предворяя возможный ответ о сортировке по значениям этого поля - я не думаю, что будет необходимость в случае автора сортировать по конкретному значению или нескольким значениям поля - ведь это нужно только для вывода?
Хотя возможно я ошибаюсь и у автора другие задачи.
Я предполагаю, что хранить в таком типе порядка 1000 значений уже может быть нерационально, но ведь то значений полей не так много - всего десяток.
Так не проще ли в основной таблице юзер добавить столбец - перечень полей, и сохранять перечень полей для каждого пользователя именно в этом типе.
Можно сохранить просто перечень числовых значений - обуславливающих вывод конкретного поля - а сам вывод прописать в php файле.
Я конечно не могу как профи предсказать рациональность такого решения, равно как скорость и нагрузку, потому как мало опыта и знания по большей части теоретические.
В связи с этим прошу профи ответить на вопрос - если такое решение нерационально - то в каких случаях будет рационально использовать тип столбца set и enum.
Кстати предворяя возможный ответ о сортировке по значениям этого поля - я не думаю, что будет необходимость в случае автора сортировать по конкретному значению или нескольким значениям поля - ведь это нужно только для вывода?
Хотя возможно я ошибаюсь и у автора другие задачи.
Спустя 11 минут, 11 секунд (27.12.2008 - 16:43) HardWoman написал(а):
Цитата |
2 таблицы всего или по таблице на каждый тип поля? |
Опять чисто теоретически
Для каких целей по таблице на каждый тип поля? Кажется в этом случае, если таблица не денормализованная - а обычные нормализованные таблицы - вариант такой
Первый вариант с использованием нормализованных таблиц
первая таблица - юзер
Вторая таблица - типы полей (id + name)
Третья таблица - ассоциативная - id юзера - id типа поля
Второй вариант с использованием денормализованной таблицы
первая таблица - юзер
Денормализованная таблица - id юзера + id типа поля+ название поля - если оно вообще нужно. Мне видится можно просто в php файле прописать вывод по идентификатору - опять же - не настаиваю, опыта нет.
Но кажется можно просто прописать значения каждого идентификатора в переменную в php файле
полей то всего ничего - не запутаетесь какой идентификатор какому полю принадлежит
Спустя 1 час, 5 минут, 52 секунды (27.12.2008 - 17:49) Сеня написал(а):
Про SET:
Выйгрыша мы от этого неполучим, ведь нужно хранить не только тип поля но и его значение, и к тому же тип поля может быть разный для разных пользователей и у одного пользователя может быть более одного поля разных типов.
Смысла в set нет.
Выйгрыша мы от этого неполучим, ведь нужно хранить не только тип поля но и его значение, и к тому же тип поля может быть разный для разных пользователей и у одного пользователя может быть более одного поля разных типов.
Смысла в set нет.
Цитата |
первая таблица - юзер Вторая таблица - типы полей (id + name) Третья таблица - ассоциативная - id юзера - id типа поля |
А четвёртая ?
id поля + значение поля..
хм. что то мутно всё.
Цитата |
Второй вариант с использованием денормализованной таблицы первая таблица - юзер Денормализованная таблица - id юзера + id типа поля+ название поля - если оно вообще нужно. Мне видится можно просто в php файле прописать вывод по идентификатору - опять же - не настаиваю, опыта нет. |
Вывод по идентификатору прописать нельзя, т.к. количество и вид полей заранее не известно.
------------------------
Наверное я бы сделал так;
Таблица USER
id /далее много нужных полей/ fields
а вот в fields бы прописал через запятую id типов полей.
и Таблица FIELDS
id / user_id / field_value
Вот как то так, если нужны имена полей то можно добавить.
Спустя 14 минут, 48 секунд (27.12.2008 - 18:03) HardWoman написал(а):
Цитата |
и у одного пользователя может быть более одного поля разных типов. |
Именно поэтому и спрашиваю, потому что этот столбец позволяет хранить несколько значений.
Хранить ведь можно идентификатор. Ладно спорить не буду до конца не разобралась.
Тогда другой вопрос - значение - то бишь имя понятно - чекбокс, рэдио и проч - такое имя может понадобиться для работы в админке
имя второе - сам вывод перед полем - допустим - укажите ваш возраст
А вот хранится ли в базе сам html код данного поля? Правильно ли это?
Спустя 9 минут, 8 секунд (27.12.2008 - 18:13) Сеня написал(а):
Цитата |
Именно поэтому и спрашиваю, потому что этот столбец позволяет хранить несколько значений. |
Вы говорите про храние в enum перечень типов полей или значений ?
Дело в том что перечень этих типов может изменяться, и нет смысла делать ALTER TABLE просто для того что бы изменить это поле, когда можно сделать простое текстовое(или INT) поле и в нём указывать тип поля(идентификатор). Ведь всё равно одним пользователем в одно время(в одной строке таблицы) может быть использовано только одно значение из перечня.
Если конечно я правильно понял что вы имеете ввиду. ^
----------------------------------------------------------------------------
Цитата |
А вот хранится ли в базе сам html код данного поля? Правильно ли это? |
Нет конечно, к чему хранить в базе html.
Спустя 18 минут, 44 секунды (27.12.2008 - 18:31) HardWoman написал(а):
Цитата |
Вывод по идентификатору прописать нельзя, т.к. количество и вид полей заранее не известно. ------------------------ Наверное я бы сделал так; Таблица USER id /далее много нужных полей/ fields а вот в fields бы прописал через запятую id типов полей. и Таблица FIELDS id / user_id / field_value Вот как то так, если нужны имена полей то можно добавить. |
Но тогда добавляется еще таблица типов. Потому что в этом случае у юзера храниться только тип поля, и нет кол ва полей этоих типов и их значений.
Либо получится денормализованная таблица такого плана.
Таблица FIELDS
id_avto_increment
id_typ_fieldvalue
typ_id
user_id
field_value
id_typ_fieldvalue напрашивается по той причине что автору нужно будет добавлять поле конктетному юзеру именно пару - тип + значение, так как полей однакового типа с разными значениями может быть несколько.
Значит к этой денормализованной таблице все равно должна быть таблица
id_avto_increment/id_typ/field_value
Спустя 13 минут, 36 секунд (27.12.2008 - 18:45) HardWoman написал(а):
Цитата |
Вы говорите про храние в enum перечень типов полей или значений ? |
Enum может хранить только одно из перечисленных значений - автору нужно хранить несколько.
я говорю о хранинии в set идентификатора id_typ_fieldvalue
Потому что тип может быть селект а список значений может быть разным.
Еще усложняется картина.
тип поля - селект
Тип списка - профессии
Тип списка - должность
Тип списка - огпыт работы
Значения типа списка профессии
Значения типа списка должность
Значения типа списка опыт работы
Мне кажется в этом случае если преположить, что возможно добавление сколько угодно типов полей и типов значений - использовать иерархии, разбитые на логические типы.
В противном случае можно получить джойны до 10 таблиц
Пришла к выводу что тут set и enum неприемлемы . Здесь для такой задачи лучшее решение может быть иерархия логических типов элементов, если будут строится сложные зависимости. Иерархия логических типов в одной таблице - их значения в другой.
Что такое сложная зависимость
тип поля - селект
Тип списка - профессии
Тип списка - зарплата
Тип списка - эквивалент зарплаты (руб, $, евро)
То есть получается сложная цепочка взаимосвязанных логических типов, и у каждого типа - может быть не только значения, но и несколько имен
Например, имя - зарплата - для админки и укажите зарплату - для вывода
Если будет три уровня как выше - можно попробовать джойнами и отдельными таблицами
Спустя 23 минуты, 11 секунд (27.12.2008 - 19:08) FatCat написал(а):
Куда-то вы в дебри подались.
Дополнительные поля профиля - это поля и значения, уникальными для пользователя должны быть значения полей.
Итого 2 принципиально разных варианта:
Во втором случае даже на "нулевом" форуме сразу будет значительный прирост нагрузки, но расти он будет линейно и не быстро.
Для нашего движка на этом хостинге точкой пересечения экспоненты с прямой будет на цифре около 50 000 зарегистрированных пользователей при суммарной длине дополнительных полей в 1000 символов.
То есть, если в форуме не ожидается 50 000 регистраций, выгодней делать на одной таблице; если больше - надо разносить, иначе есть риск "затыка", когда потребление ресурсов начнет расти как снежный ком.
Дополнительные поля профиля - это поля и значения, уникальными для пользователя должны быть значения полей.
Итого 2 принципиально разных варианта:
- все возможные для всех групп дополнительные поля хранятся в таблице пользователей; заполняются по мере заполнения пользователем; условиями пхп определяется обязательность или необязательность заполнения, видимость или скрытность; либо же эти условия выносим уже в отдельную таблицу...
- все дополнительные поля выносятся в связанные таблицы.
Во втором случае даже на "нулевом" форуме сразу будет значительный прирост нагрузки, но расти он будет линейно и не быстро.
Для нашего движка на этом хостинге точкой пересечения экспоненты с прямой будет на цифре около 50 000 зарегистрированных пользователей при суммарной длине дополнительных полей в 1000 символов.
То есть, если в форуме не ожидается 50 000 регистраций, выгодней делать на одной таблице; если больше - надо разносить, иначе есть риск "затыка", когда потребление ресурсов начнет расти как снежный ком.
Спустя 43 минуты, 7 секунд (27.12.2008 - 19:51) HardWoman написал(а):
Цитата |
Куда-то вы в дебри подались. Дополнительные поля профиля - это поля и значения, уникальными для пользователя должны быть значения полей. |
Да нет это не мои дебри. Вот что написал автор
Цитата |
Создаю для них обязательные и необязательные поля (о себе, город, хобби и т.д.), выпадающие списки, чекбоксы и т.д. (на выбор - любой элемент формы). |
Цитата |
Сложность здесь в том, что кол-во и типов этих дополнительных полей может быть сколько угодно, при этом они могут изменяться, добавляться и удаляться в процессе использования |
Я так понимаю, что автор предполагает выводить определенный набор определенных форм для заполнения конкретным группам пользователей. И САМОЕ СЛОЖНОЕ помимо этого манипулировать ими по своему усмотрению.
Отсюда - достаточно сложные скрипты по манипулированию этими формами и поддержки ссылочной целосности.
А чекбоксы? А если это наборы чекбоксов ? Или список селекст с множественным выбором?
Они предполагают что значений может быть множество. И получится раздутая до немогу денормализованная таблица
_____________