代码之家  ›  专栏  ›  技术社区  ›  Jacob Mattison

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

  •  4
  • Jacob Mattison  · 技术社区  · 15 年前

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

    例如,

    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?哈斯塔特布斯?哈斯塔图斯?)为每个人。这样,如果我想查询每个拥有状态C的人,就不必知道计算状态C的所有规则;我只需检查标志。

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

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

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

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

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

    3 回复  |  直到 15 年前
        1
  •  2
  •   Bob Jarvis - Слава Україні    15 年前

    在这种情况下,我建议应用沃德·坎宁安的问题——扪心自问“可能最简单的事情是什么?”。

    在本例中,最简单的事情可能是创建一个视图,该视图查看数据的存在状态,并进行计算和计算以生成您所关心的所有字段。现在,加载你的数据库并尝试它。够快了吗?如果是的话,很好-你做了最简单的事情,结果很好。如果不够快,很好-第一次尝试不起作用,但您已经在视图代码中映射了规则。现在,您可以继续尝试“最简单的事情”的下一个迭代——也许您可以编写一个后台任务,监视插入和更新,然后跳入重新计算标志。如果行得通的话,很好很好。如果没有,则转到下一个迭代……等等。

    分享和享受。

        2
  •  0
  •   ttomsen    15 年前

    我建议不要将状态设置为列名,而是使用状态id和值。例如具有ID和Value列的customer status表。

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

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

        3
  •  0
  •   Jeffrey Kemp    15 年前

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

    但是,如果一次调用多行(例如用于报告),则该函数的性能可能不够好。所以,如果您在Oracle 11g上,可以通过添加 virtual columns (搜索“虚拟列”)到基于该函数的相关表。这个 Result Cache 功能也应该提高功能的性能。