2010-10-06 29 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. 

乘以几十状态甚至几百个团体和属性。人员,组和属性都在数据库中。

虽然这将Java应用程序被消耗掉,我们也希望能够直接对数据库运行报告,所以这将是最好的,如果设定的计算状态的人提供在数据层面。

我们目前的设计方案,然后,就是有一个由一组布尔标志(hasStatusA?hasStatusB?hasStatusC?)每个人的表或视图。这样,如果我想查询具有状态C的每个人,我不必知道计算状态C的所有规则;我只是检查国旗。

(需要注意的是,在现实生活中,这些标志将有更多有意义的名字:isEligibleForReview?isPastDueForReview?等等)。

所以一个),这是一种合理的方法,和b)如果是这样,什么是计算这些标志的最好方法?

我们正在考虑用于计算标志的一些选项:

  1. 让一组标志的视图,并使用SQL或PL-SQL实时的基础数据计算的标志值(这是一个Oracle数据库)。这样的价值总是准确的,但性能可能会受到影响,规则必须由开发人员维护。

  2. 使该组标志包括静态数据,并使用某种类型的规则引擎来保持这些标志上最新的数据的变化。这样可以更容易地维护规则,但是在给定的时间点,标志可能不准确。 (如果我们用这种方法去,有一个规则引擎,可以轻松地以这种方式操纵数据库中的数据?)

+0

您的数据多久更新一次?我们在说这些状态可能会改变每分钟,每小时,每天,每周吗? – JNK 2010-10-06 17:56:16

+1

你的例子读起来像Prolog。 – Dave 2010-10-06 17:57:23

+0

属性可能每天都在变化;团体可能每月。理想情况下,属性更改应在一分钟左右内完成。规则本身应该更少地改变;也许每隔几个月。 – 2010-10-06 18:27:05

回答

2

在这样的情况下,我建议将沃德·坎宁安的question-问自己“什么是最简单的事情,可能可行?“。

在这种情况下,最简单的事情可能会拿出自己看数据,因为它存在并执行计算和计算产生你所关心的所有字段的视图。现在,加载你的数据库并尝试一下。速度够快吗?如果是这样,好 - 你做了最简单的事情,它运作良好。如果速度不够快,很好 - 第一次尝试不起作用,但是您已经在视图代码中绘制了规则。现在,您可以继续尝试“最简单的事情”的下一次迭代 - 也许您会编写一个监视插入和更新的后台任务,然后跳转到重新计算标志。如果这样做,罚款和丹迪。如果没有,请继续下一个迭代......等等。

分享和享受。

+0

奥卡姆剃刀:) – 2010-10-06 19:44:00

0

我会建议不要将状态作为列名称,而是使用状态ID和值。例如包含ID和值列的客户状态表。

我会有两种更新状态的方法。一个存储过程,它具有所有的逻辑或者调用单独的存储过程来确定每个状态。您可以通过为每个状态评估提供一个函数来实现所有这些动态,然后一个存储过程可以调用每个函数。第二种方法是拥有任何存储过程,更新用户信息,调用存储过程,根据当前数据更新所有用户状态。这两种方法将允许您对已更改的数据进行实时更新,如果添加新状态,则可以调用该方法以使用新逻辑更新所有状态。

希望您对用户数据有一点更新,例如用户更新存储过程,并且您可以将状态更新存储过程调用放在该过程中。这也可以节省必须每n秒安排一次任务来更新状态。

0

我会考虑的一个选项是每个标志由一个确定性函数支持,该函数返回给定相关数据的最新值。

但是,如果您一次对多行进行调用(例如,报告),该函数可能表现不佳。因此,如果您使用的是Oracle 11g,则可以通过将virtual columns(搜索“虚拟列”)添加到基于该函数的相关表中来解决此问题。 Result Cache功能也应该改善功能的性能。