У нас есть система php/mysql с примерно 5 основными объектами. Теперь нам нужно добавить возможность для клиентов создавать настраиваемые поля для некоторых из этих сущностей для каждого проекта.
Они будут содержать метку, ключ, тип, значение по умолчанию и возможные допустимые значения.
Это делается для того, чтобы они могли добавить настраиваемое поле даты или настраиваемое раскрывающееся меню в пользовательский интерфейс и сохранить это значение для определенного объекта.
Как лучше всего хранить такие данные в базе данных MySQL? Мне нужно сохранить как конфиг для поля, так и текущее значение для конкретного объекта.
Здесь я рассмотрел различные варианты. https://ayende.com/blog/3498/multi-tenancy-extensible-data-model
Но на самом деле это не уровень аренды, а уровень проекта.
Я подумал...
- Таблица CustomFields для хранения конфигурации поля по типу сущности и идентификатору проекта.
- Таблица CustomFieldValues для хранения значения, сохраненного для поля — строка для каждого поля ( entity_id | field_id | field_value)
Затем мы создаем отношения между сущностями и этими пользовательскими значениями при извлечении сущностей.
Проблема заключается в том, что в таблице значений будет столько же строк, сколько и настраиваемых полей, поэтому сохранение объекта приведет к X дополнительных строк. Кроме того, они имеют версии, поэтому после создания новой версии для этой новой версии будет создано еще X строк.
Кроме того, вы не можете индексировать поля по имени, я думаю, что соединения станут довольно сложными, поскольку вам нужно присоединиться к конфигурации и значениям, чтобы построить пару значений ключа, чтобы вернуться к объекту, и как бы вы выбрали на основе имя пользовательского поля, когда имя поля на самом деле было значением?
Я не хочу добавлять в таблицу динамические столбцы, так как это повлияет на ВСЕ сущности во всей системе, а не только на те, что в текущем клиенте/проекте.
Другой вариант — сохранить значения в столбце JSON.
Это может быть в самой строке объекта customFields
или аналогичной. Это предотвратит появление дополнительных строк в поле, но также имеет проблемы с отсутствием индексации и т. д., и все равно необходимо присоединиться к таблице конфигурации. Однако вы можете выполнять запросы по имени свойства, если key=value
хранится в JSON... WHERE entity.customFields->"$.myCustomFieldName" > 1
.
Хранение имени файла в json означает, что вы не можете изменить его после создания без особых проблем.
Если у кого-нибудь есть какие-либо советы о подходах к этому или статьи, которые указывают мне на это, я был бы очень признателен - я уверен, что это было решено много раз раньше....