применение бизнес-правил на уровне базы данных

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

Например,

if a person is part of group X 
and (if they have attribute O) has either attribute P or attribute Q, 
or (if they don't have attribute O) has attribute P but not Q,
and don't have attribute R, 
and aren't part of group Y (unless they also are part of group Z), 
then status A is true. 

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

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

Таким образом, наш текущий план проектирования состоит в том, чтобы иметь таблицу или представление, состоящее из набора логических флагов (hasStatusA? hasStatusB? hasStatusC?) для каждого человека. Таким образом, если я хочу запросить всех, кто имеет статус C, мне не нужно знать все правила для вычисления статуса C; Я просто проверяю флаг.

(Обратите внимание, что в реальной жизни флаги будут иметь более осмысленные имена: isEligibleForReview?, isPastDueForReview? и т. д.).

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

Некоторые варианты, которые мы рассматриваем для вычисления флагов:

  1. Сделайте набор флагов представлением и вычислите значения флагов из базовых данных в режиме реального времени, используя SQL или PL-SQL (это Oracle DB). Таким образом, значения всегда точны, но может пострадать производительность, и разработчику придется поддерживать правила.

  2. Сделайте набор флагов состоящим из статических данных и используйте какой-либо механизм правил, чтобы поддерживать эти флаги в актуальном состоянии по мере изменения базовых данных. Таким образом, правила легче поддерживать, но флаги потенциально могут быть неточными в данный момент времени. (Если мы выберем этот подход, существует ли механизм правил, который может легко манипулировать данными в базе данных таким образом?)


person Jacob Mattison    schedule 06.10.2010    source источник
comment
Как часто ваши данные будут обновляться? Мы говорим, что эти статусы могут меняться каждую минуту, час, день, неделю?   -  person JNK    schedule 06.10.2010
comment
Ваш пример читается как Пролог.   -  person Dave    schedule 06.10.2010
comment
Атрибуты могли меняться ежедневно; группы, возможно, ежемесячно. Статусы в идеале должны быть точными в течение минуты или около того после изменения атрибута. Сами правила должны меняться реже; может раз в несколько месяцев.   -  person Jacob Mattison    schedule 06.10.2010
comment
о прологе: это правда, хотя мой пример предназначался больше для того, чтобы показать, как правила будут вложены в логику if/then и т. д. Я немного читал о концепции дедуктивных баз данных, которые используют правила, обычно в прологе, для вывода набор фактов, основанный на данных. Это прекрасно, но я не думаю, что есть такие готовые к работе системы, и я сомневаюсь, что мои коллеги захотят изучать пролог (а я сам не использовал пролог уже 20 лет).   -  person Jacob Mattison    schedule 06.10.2010


Ответы (3)


В подобном случае я предлагаю применить вопрос Уорда Каннингема: спросите себя: «Какая самая простая вещь может сработать?».

В этом случае самым простым может быть создание представления, которое просматривает данные в том виде, в каком они существуют, и выполняет расчеты и вычисления для создания всех нужных вам полей. Теперь загрузите свою базу данных и попробуйте. Это достаточно быстро? Если да, то хорошо — вы сделали самое простое, что только можно было сделать, и все получилось. Если это НЕ достаточно быстро, хорошо - первая попытка не сработала, но у вас есть правила, указанные в коде представления. Теперь вы можете перейти к следующей итерации «самой простой вещи» — возможно, вы напишете фоновую задачу, которая следит за вставками и обновлениями, а затем перескакивает, чтобы пересчитать флаги. Если это работает, хорошо и денди. Если нет, перейдите к следующей итерации... и так далее.

Делитесь и наслаждайтесь.

person Bob Jarvis - Reinstate Monica    schedule 06.10.2010

Я бы посоветовал не делать статусы в виде имен столбцов, а использовать идентификатор и значение статуса. например, таблица статуса клиента со столбцами ID и Value.

У меня было бы два метода обновления статусов. Одна хранимая процедура, которая либо имеет всю логику, либо вызывает отдельные хранимые процедуры для определения каждого статуса. вы могли бы сделать все это динамическим, имея функцию для каждой оценки состояния, и один сохраненный процесс мог бы затем вызывать каждую функцию. Второй метод заключается в том, чтобы любой сохраненный процесс (процессы), который обновляет информацию о пользователе, вызывал сохраненный процесс для обновления всех статусов пользователей на основе текущих данных. Эти два метода позволят вам иметь обновления в реальном времени для измененных данных, и если вы добавите новый статус, вы можете вызвать метод для обновления всех статусов с новой логикой.

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

person ttomsen    schedule 06.10.2010

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

Однако функция может работать недостаточно хорошо, если вы вызываете ее для многих строк одновременно (например, для создания отчетов). Итак, если вы используете Oracle 11g, вы можете решить эту проблему, добавив виртуальные столбцы (ищите "виртуальный столбец") в соответствующие таблицы на основе функции. Функция Кэш результатов должна улучшить также выполнение функции.

person Jeffrey Kemp    schedule 07.10.2010