Как создать базу данных для пользовательских полей? - PullRequest
135 голосов
/ 24 февраля 2011

Мои требования:

  • Необходимость динамического добавления пользовательских полей любого типа данных
  • Необходимость быстрого запроса UDF
  • Необходимо иметь возможность выполнять вычисления для пользовательских функций на основе типа данных
  • Необходимо иметь возможность сортировать пользовательские функции на основе типа данных

Другая информация:

  • В первую очередь я ищу производительность
  • Существует несколько миллионов основных записей, к которым могут быть прикреплены данные UDF
  • Когда я в последний раз проверял, в нашей текущей базе данных было более 50 миллионов записей UDF
  • В большинстве случаев UDF прикрепляется только к нескольким тысячам основных записей, но не все из них
  • UDF не объединяются или не используются в качестве ключей.Это просто данные, используемые для запросов или отчетов

Параметры:

  1. Создать большую таблицу с помощью StringValue1, StringValue2 ... IntValue1, IntValue2, ..и т.д. Я ненавижу эту идею, но рассмотрю ее, если кто-то скажет мне, что она лучше других идей и почему.

  2. Создайте динамическую таблицу, которая добавляет новый столбец по требованию какнеобходимо.Мне также не нравится эта идея, поскольку я чувствую, что производительность будет низкой, если вы не проиндексировали каждый столбец.

  3. Создайте одну таблицу, содержащую UDFName, UDFDataType и Value.Когда добавляется новый UDF, генерирует View, который извлекает только эти данные и анализирует их в соответствии с указанным типом.Элементы, которые не соответствуют критериям синтаксического анализа, возвращают NULL.

  4. Создайте несколько таблиц UDF, по одной на тип данных.Таким образом, у нас будут таблицы для UDFStrings, UDFDates и т. Д. Вероятно, будет сделано то же самое, что и для # 2, и будет автоматически генерироваться представление при каждом добавлении нового поля

  5. XML DataTypes?Я не работал с ними раньше, но видел, как они упоминались.Не уверен, что они дадут мне результаты, которые я хочу, особенно с производительностью.

  6. Что-то еще?

Ответы [ 14 ]

1 голос
/ 24 февраля 2011

SharePoint использует вариант 1 и имеет разумную производительность.

0 голосов
/ 23 марта 2019

Я бы порекомендовал # 4 , поскольку этот тип системы использовался в Magento , которая является высоко аккредитованной платформой CMS для электронной коммерции. Используйте одну таблицу для определения пользовательских полей, используя fieldId & label столбцы. Затем, иметь отдельные таблицы для каждого типа данных, и в каждой из этих таблиц есть индекс, который индексирует по fieldId и тип данных значение столбцы. Затем в своих запросах используйте что-то вроде:

SELECT *
FROM FieldValues_Text
WHERE fieldId IN (
    SELECT fieldId FROM Fields WHERE userId=@userId
)
AND value LIKE '%' + @search + '%'

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

По своему опыту я работал на нескольких веб-сайтах Magento, которые обслуживают миллионы пользователей в месяц, размещают тысячи продуктов с настраиваемыми атрибутами продуктов, а база данных легко справляется с нагрузкой даже для отчетов.

Для создания отчетов вы можете использовать PIVOT для преобразования значений Поля таблицы label в имена столбцов, а затем преобразовать результаты запроса из каждой таблицы типов данных в эти поворотные столбцы.

0 голосов
/ 23 декабря 2017

Наша база данных поддерживает приложение SaaS (программное обеспечение службы поддержки), в котором пользователи имеют более 7 тыс. «Пользовательских полей».Мы используем комбинированный подход:

  1. (EntityID, FieldID, Value) таблица для поиска данных
  2. поля JSON в таблице entities, которое содержит все значения сущностей, используется для отображения данных.(таким образом, вам не нужен миллион JOIN'ов, чтобы получить значения значений).

Вы можете дополнительно разделить # 1, чтобы получить «таблицу на тип данных», такую ​​как этот ответ предполагает, что таким образом вы даже можете индексировать свои UDF.

PS Пару слов в защиту подхода «Entity-Attribute-Value», который каждый продолжает ругать.Мы использовали # 1 без # 2 в течение десятилетий, и это работало просто отлично.Иногда это деловое решение.У вас есть время, чтобы переписать ваше приложение и перепроектировать БД, или вы можете через пару долларов на облачных серверах, которые действительно дешевы в наши дни?Кстати, когда мы использовали подход № 1, наша БД содержала миллионы сущностей, к которым обращались 100 тысяч пользователей, а двухъядерный 16-Гбайт сервер с 16 ГБ работал нормально (на самом деле «r3» vm на AWS).

0 голосов
/ 07 марта 2011

В комментариях я видел, как вы говорили, что поля UDF предназначены для вывода импортированных данных, которые не отображаются пользователем должным образом.

Возможно, другой вариант - отследить количество пользовательских функций, созданных каждым пользователем, и заставить их повторно использовать поля, сказав, что они могут использовать 6 (или некоторые другие одинаково случайные ограничения) верхних значений пользовательских полей.

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

Теперь я бы выбрал вариант 4 (РЕДАКТИРОВАТЬ) с добавлением ссылки для пользователей:

general_data_table
id
...


udfs_linked_table
id
general_data_id
udf_id


udfs_table
id
name
type
owner_id --> Use this to filter for the current user and limit their UDFs
string_link_id --> link table for string fields
int_link_id
type_link_id

Теперь убедитесь, что вы создали представления для оптимизации производительности и получения правильных индексов. Этот уровень нормализации уменьшает размер базы данных, но делает ваше приложение более сложным.

...