【问题标题】:applying business rules at the database level在数据库级别应用业务规则
【发布时间】:2011-04-21 23:40:28
【问题描述】:

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

例如,

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

【问题讨论】:

  • 您的数据多久更新一次?我们是在说这些状态可能每分钟、每小时、每天、每周都会改变吗?
  • 你的例子读起来像 Prolog。
  • 属性可以每天更改;团体可能每月一次。理想情况下,状态应该在属性更改后的一分钟左右内准确无误。规则本身应该不那么频繁地改变;可能每隔几个月。
  • re prolog:确实如此,尽管我的示例更多地是为了说明规则将如何嵌套 if/then 逻辑等。我确实阅读了一些关于“演绎数据库”的概念,其中使用规则,通常在序言中,根据数据推断一组事实。这很完美,但我不认为有任何这样的现实世界就绪系统,而且我怀疑我的同事会想要学习 prolog(而且我自己已经 20 年没有使用过 prolog)。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      分享和享受。

      【讨论】:

        猜你喜欢
        • 2019-11-17
        • 1970-01-01
        • 2011-12-15
        • 1970-01-01
        • 2023-03-20
        • 2016-06-07
        • 2023-03-14
        • 1970-01-01
        • 2023-03-18
        相关资源
        最近更新 更多