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

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

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

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

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

4

3 回答 3

2

在这种情况下,我建议应用 Ward Cunningham 的问题——问自己“什么是最简单的可行的方法?”。

在这种情况下,最简单的事情可能是提出一个视图来查看存在的数据并进行计算和计算以生成您关心的所有字段。现在,加载您的数据库并尝试一下。速度够快吗?如果是这样,那很好——你做了最简单的事情,结果很好。如果速度不够快,那很好——第一次尝试没有成功,但您已经在视图代码中绘制了规则。现在您可以继续尝试“最简单的事情”的下一次迭代——也许您编写一个后台任务来监视插入和更新,然后跳进去重新计算标志。如果那行得通,那就太好了。如果没有,则进行下一次迭代……以此类推。

分享和享受。

于 2010-10-06T18:56:32.887 回答
0

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

但是,如果您一次为多行调用该函数(例如,用于报告),该函数的性能可能不够好。因此,如果您使用的是 Oracle 11g,则可以通过将虚拟列(搜索“虚拟列”)添加到基于函数的相关表中来解决此问题。结果缓存功能也应该提高功能的性能。

于 2010-10-07T00:12:19.417 回答
0

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

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

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

于 2010-10-06T19:11:56.233 回答