Как бы вы могли создавать и хранить определяемые пользователем настраиваемые поля в базе данных SQL?

Мне нужно разрешить пользователям добавлять новые поля в запись, например. если есть запись контакта, пользователь может захотеть добавить числовое поле «SSN» и поле даты / календаря «Дата рождения». Конечно, они будут делать это через пользовательский интерфейс.

Эти поля должны быть доступны для ввода во всех контактных записях.

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


person Alex    schedule 07.06.2009    source источник
comment
Честно говоря, я думаю, что вы навлекаете на себя проблемы, спрашивая отдельных пользователей об их требованиях на лету. Например, если у вас есть 10 человек, которым нужна одна и та же информация, но назовите ее десятью разными способами, у вас будет много сложностей с очень небольшой пользой. Возможно, было бы лучше встретиться с пользователями и прийти к консенсусу, чем делать что-то спонтанно.   -  person Michael Todd    schedule 07.06.2009
comment
Вы правы на 100%. Однако я придерживаюсь этого требования :(   -  person Alex    schedule 07.06.2009
comment
Я достиг этого во многих приложениях. Когда вы реализуете этот тип требований, это очень сложно, но это даст пользователю больше гибкости для добавления настраиваемых полей.   -  person Muhammad Akhtar    schedule 07.06.2009


Ответы (3)


Мы добавляем почти во все наши приложения / продукты дополнительную поддержку атрибутов / полей для обеспечения гибкости для пользователя
Как и у нас есть категория продукта, в категории клиент может определить дополнительный атрибут любого продукта
, что мы делаем на уровне БД:
Таблица категорий имеет дополнительный столбец, например: Text1Att, Text2Att ... для поддержки текстового значения, Num1Att, Num2Att ... для поддержки числового значения, Date1Att, Date2Att ... для поддержки значения datetime , ID1Att, ID2Att ... поддержка ID из другой таблицы, например, вы можете добавить раскрывающийся список, список, ...
здесь все столбцы имеют тип данных String.
здесь мы храним

метаинформацию, например, для Text1Att мета
SSN; textbox; 50; true; false; Null;
Заголовок поля; Тип элемента управления; Максимальная длина; Обязательное поле; Требуется пользовательская проверка; Пользовательское сообщение проверки;
место рождения; текстовое поле; 100; истина; истина; недопустимое значение;
То же самое для числового поля ...
для даты метаинформация будет выглядеть так:
дата рождения; календарь; истина; истина; недействительная дата;
Заголовок поля; Управление календарем или может быть другим; требуется; это настраиваемая проверка; Пользовательское сообщение проверки;


В таблице продуктов добавляется такое же количество столбцов и тип данных text1Att, .. is varchar, num1Att has numeric, date1Att has datetime, ID1Att has int

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


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

person Muhammad Akhtar    schedule 07.06.2009
comment
Хотя это решение кажется уродливым, оно намного лучше с точки зрения возможности поиска. Выполнение этого способа, описанного в принятом ответе, делает очень дорогим (с точки зрения производительности) поиск многих полей. - person Erich Kitzmueller; 07.06.2009

Имейте таблицу, в которой хранятся имена и типы полей.

field_ID     INT
field_name   VARCHAR
field_type   ENUM('int','float','text','richtext')

Имейте таблицу, в которой хранится ссылка на запись в таблице записей, ссылка на запись в таблице полей и значение поля.

fieldvalue_fieldID   INT
fieldvalue_recordID  INT
fieldvalue_value     BLOB

Еще одна проблема - сделать его доступным для поиска: вам нужно будет взять любой доступный для поиска контент из этого fieldvalue_value и проиндексировать его. Это будет зависеть от базы данных. В MySQL вы можете сделать это значение TEXT и добавить к нему индекс MySQL FULLTEXT.

person thomasrutter    schedule 07.06.2009
comment
Учитывая ваши требования, это, вероятно, самый простой способ сделать что-то. Удачи. - person Michael Todd; 07.06.2009
comment
Ах да, антипаттерн EAV. - person Neil McGuigan; 12.04.2013
comment
Дополнительная информация здесь и здесь - person thomasrutter; 12.04.2013
comment
Это анти-шаблон, если он используется для чего-либо, кроме пользовательских полей, определенных пользователем. Если именно так вы, разработчик, собираетесь создавать свои собственные поля базы данных, это определенно неправильный путь, потому что вы без нужды сделаете свою базу данных более сложной и менее эффективной. Этот метод подходит, когда вам абсолютно необходимо, чтобы ваши пользователи могли создавать настраиваемые поля без изменения структуры базы данных (например, ALTER TABLE). - person thomasrutter; 14.04.2014

Ваши лучшие варианты:

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

  2. Используйте поле XML и базу данных, которая поддерживает индексы и запросы к содержимому этого поля.

Их рекомендует Мартин Фаулер, здесь: http://martinfowler.com/bliki/UserDefinedField.html

person Neil McGuigan    schedule 20.01.2013