2013-06-09 5 views
1

Сценарий

Допустим, пользователь является продавцом. Модель User имеет много log_entries, которые используются как ежедневный журнал для данных о продажах. Пользователь также имеет настройки, которые позволяют им выбирать, какие поля видны в форме log_entry. Итак, если они выбирают ананасы, бананы и виноград ... это поля, которые будут в форме. Если эти варианты изменятся, данные не будут потеряны ... просто не видны в форме. Теперь, скажем, пользователь только что выбрал аккаунт для продажи клюквы, но клюква не является избранным атрибутом в форме пользовательских настроек. Они должны иметь возможность создать эту «категорию». Теперь сезон ананасов закончился, поэтому они заходят туда и снимают коробку с ананасом и проверяют коробку с клубникой. Теперь, когда они идут, чтобы ввести данные в свой журнал, будет поле данных для клубники, но не ананасы. Данные ананаса не исчезли ... его просто не показывают.Динамические столбцы таблицы, основанные на пользовательских предпочтениях

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

Как я могу управлять динамическими столбцами db? Может ли postgres hstore справиться с этим?

Одна строка - это запись, принадлежащая пользователю, основанная на дате. Каждый столбец содержит данные, относящиеся к атрибуту (например, ... один столбец может быть названа «клубника», и это будет держать, сколько единиц было продано в тот же день)

+0

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

+0

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

+0

Еще один вариант, который я хочу сделать, это создать определенное количество пользовательских столбцов в базе данных, скажем ... custom_one, custom_two и т. Д. (Возможно, 10 из них). Затем создайте модель Usercustom с двумя полями ... custom_col_ref: string и custom_col_label: string. custom_col_ref будет хранить фактическое имя столбца, где хранятся данные, а custom_col_label будет хранить метку, которая будет использоваться в форме. Затем используйте оператор if, чтобы показать/скрыть это поле в форме ... ", если Usercustom.find_by_custom_col_ref (" custom_one ") существует?" ... показать поле для этого столбца в форме. – hellion

ответ

3

Обычные подходы к этому являются:

  • EAV
  • hstore
  • XML
  • JSON

См:

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

Добавление столбцов с динамическими звуками DDL разумно вначале, но есть ограничения на количество столбцов, которые вы можете сохранить и как может быть «широкая» строка. Производительность сканирования таблицы ухудшается, так как вы добавляете больше столбцов, хотя «редкие» столбцы, которые в основном нулевые, относительно дешевы. Для добавления столбца требуется эксклюзивная блокировка, что может занять время, чтобы попасть в занятую систему, хотя добавление столбца самоисполняется очень быстро, если оно не определено как NOT NULL DEFAULT .... Сначала это будет работать хорошо, но я подозреваю, что вы пожалеете об этом позже.

+2

«Сначала добавление колонок с динамическими DDL-звуками разумно», а затем вам нужно убедить ORM играть хорошо с такими вещами. Вероятно, вам лучше поработать на яблоках в ведерке рыболовных крючков. –

+1

@muistooshort Ах, да, ОРМ. Веселые времена. Восхитительная аналогия. –

+0

Спасибо, Крейг. Итак, если я знаю, что 90% полей будут нужны пользователям, было бы целесообразно добавлять эти столбцы в базу данных ... хотя для некоторых или многих пользователей многие из этих столбцов всегда будут пустыми? Я использую postgres, поэтому я мог бы использовать hstore ... но, все еще выясняя, как это сделать в моем видении. – hellion

0

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

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

Затем, на странице настроек предпочтений пользователей У меня есть раздел под названием Fruit (если у пользователя есть какие-либо предпочтения Fruit). Запрос просто ищет таблицу предпочтений для пользователя, сопоставляющего current_user, matchref match «Fruit» и поиск записи фруктов с использованием несвязанного хранимого идентификатора.

Возможно, я не очень хорошо объяснил это ... но, может быть, это поможет кому-то еще сделать что-то подобное.

+0

Я в конечном итоге использовал hstore. Определенно, путь. – hellion

Смежные вопросы