2010-10-06 2 views
4

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

Например,

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. 

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

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

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

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

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

Некоторых вариантов мы рассматриваем для вычислительных флажков:

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

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

+0

Как часто обновляются ваши данные? Мы говорим, что этот статус может меняться каждую минуту, час, день, неделю? – JNK

+1

Ваш пример читается как Пролог. – Dave

+0

Атрибуты могут меняться ежедневно; групп, возможно, ежемесячно. Статусы в идеале должны быть точными в течение минуты или около того относительно изменения атрибута. Сами правила должны меняться реже; может быть, каждые несколько месяцев. –

ответ

2

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

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

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

+0

Бритва Оккама :) –

0

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

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

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

0

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

Функция может не работать достаточно хорошо, однако, если вы вызываете ее для многих строк за раз (например, для отчетов). Итак, если вы используете Oracle 11g, вы можете решить эту проблему, добавив virtual columns (поиск «виртуального столбца») в соответствующие таблицы на основе функции. Функция Result Cache также должна улучшить производительность функции.

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