在数据库级别应用业务规则

时间:2010-10-06 17:53:14

标签: sql database oracle rule-engine business-rules

我正在开展一个项目,在这个项目中,我们需要为存储在数据库中的大量人员确定某些类型的状态。确定这些状态的业务规则相当复杂,可能会发生变化。

例如,

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?等。)

所以a)这是一种合理的方法,并且b)如果是这样,那么计算这些标志的最佳方法是什么?

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

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

  2. 使标志集由静态数据组成,并使用某种类型的规则引擎在基础数据发生变化时使这些标志保持最新。这样可以更容易地维护规则,但是在给定的时间点,标志可能是不准确的。 (如果我们采用这种方法,是否有可以通过这种方式轻松操作数据库中的数据的规则引擎?)

3 个答案:

答案 0 :(得分:2)

在这样的情况下,我建议应用Ward Cunningham的问题 - 问自己“什么是最简单的可能有用的东西?”。

在这种情况下,最简单的事情可能是提出一个视图,该视图查看数据是否存在,并进行计算和计算以生成您关心的所有字段。现在,加载您的数据库并试用它。它足够快吗?如果是这样,那么好 - 你做了最简单的事情而且效果很好。如果它不够快,那么好 - 第一次尝试不起作用,但是您已经在视图代码中映射了规则。现在,您可以继续尝试“最简单的事情”的下一次迭代 - 也许您编写一个后台任务来监视插入和更新,然后跳转来重新计算标志。如果这工作,罚款和花花公子。如果没有,请转到下一个迭代......依此类推。

分享并享受。

答案 1 :(得分:0)

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

我有两种更新状态的方法。一个存储过程,要么具有所有逻辑,要么分别存储过程以确定每个状态。你可以通过为每个状态评估设置一个函数来使所有这些动态化,然后一个存储过程可以调用每个函数。第二种方法是拥有任何存储的proc(s),更新用户信息,调用存储过程以根据当前数据更新所有用户状态。这两种方法允许您对已更改的数据进行实时更新,如果添加新状态,则可以调用该方法以使用新逻辑更新所有状态。

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

答案 2 :(得分:0)

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

但是,如果您一次调用多行(例如用于报告),则该函数可能无法正常运行。因此,如果您使用的是Oracle 11g,则可以通过基于函数将virtual columns(搜索“虚拟列”)添加到相关表来解决此问题。 Result Cache功能也可以提高功能的性能。