【问题标题】:Storing conditional logic expressions/rules in a database在数据库中存储条件逻辑表达式/规则
【发布时间】:2010-10-07 10:23:03
【问题描述】:

如何使用 RDBMS 存储逻辑表达式?

我标记对象并希望能够基于这些标记构建真实陈述。 (这些可能被视为虚拟标签。)

标签
new
for_sale
used
offer

规则
second_hand_goods = (!new or used) and for_sale
new_offer = new and offer
second_hand_offer = second_hand_goods and offer

  • 规则应该能够引用标记和其他规则。
  • 最好使用 hibernate 可以轻松访问的架构。
  • 最好可以在一次选择/调用中检索整个规则?

你们如何在数据库中存储表达式和业务规则?

提前致谢。

更新
需要明确的是,这些规则不是供数据库内部使用的,而是由需要保留这些标签和规则的外部应用程序创建和使用的。谢谢。

【问题讨论】:

    标签: database hibernate rdbms


    【解决方案1】:

    从实用的角度来看,如果计算所需的所有列都位于同一个表上,您可以在数据库中创建计算字段 - 计算字段只能在单个记录中工作。大多数现代 DBMS 平台都支持此功能。

    从理论上讲,您正在进入Semantic Data Modelling。这方面最好的论文是 Hammer 和 MacLeods Ruritanian Oil Tankers 论文,它描述了一种富有想象力的语义数据建模符号 SDM。 SDM 使用结构化的英语类型符号来标记您描述的那种数据库规则。如果您想概括您的能力并且不介意为 SDM 编写解析器,您可以创建一个可以配置这种逻辑的规则引擎。这种类型的模型也应该可以很好地适应 O/R 映射器。

    不利的一面是,制作这种工具会非常耗时,因此只有在您对管理数据语义的需求非常大的情况下才值得这样做。对于您引用的示例,它可以轻松地适应过度杀伤力的领域,但如果您的问题更大,那么构建这样的东西可能是值得的。如果您不想编写解析器,您可以创建一个 XML 模式来标记类似 SDM 的语言。

    【讨论】:

      【解决方案2】:

      管理嵌套/括号会变得相当复杂并且容易出错。我过去这样做的方法是使用 XML 来定义逻辑,因为它可以很好地处理嵌套。使用 SQL Server 2005 或更高版本,您还可以将其很好地存储在单个表中。

      您的二手商品逻辑可以存储为...

      <logic type="and">
          <logic type="or">
              <logic type="not">
                  <value type="new" />
              </logic>
              <value type="used" />
          </logic>
          <value type="for_sale" />
      </logic>
      

      很抱歉,这不是对您问题的实际答案,而只是另一种做事方式。我刚刚发现它过去对我有用。

      【讨论】:

      • 根据我的经验,我只能说尝试使用 XML 作为编程语言很糟糕。
      • 我完全同意,但是,这纯粹是为了存储基于逻辑的公式。主要的一点是,我宁愿使用 XML 的现成嵌套功能,而不是将这种机制构建到数据库中。
      • 嘿,我有类似的情况,我正在考虑使用这样的设计......(一个 SqlXml 字段)更重要的是,整个表达式只是为了我系统中一个非常微不足道的功能,只是想要它询问这是否“好的”它的设计条款?由于许多像上面的人有一些复杂的方法来存储它而不用 xml,在数据库中。@anton
      • @RobinDay 看起来像我正在寻找的东西。谢谢!您能否提供一些想法如何将此 XML 解析为 PHP 表达式?
      • @DenisO。我知道它晚了几年,但这里有一些 PHP,我有一些类似的处理方法——它有实现的方法,或者,至少,最多,和 sum gist.github.com/bravadomizzou/b16d12d6e0f8994526468dc2d9937a47
      【解决方案3】:

      默认情况下,在我充分理解问题并找出解决方案之前,我不会将业务规则存储在数据库中。这些属于代码。但是,任何规则总有例外,您可以使用 RDBMS 的存储过程和/或函数来封装这些规则(前提是您的数据库有它们)。但是,正如我所说,理想情况下,您将在代码中以有意义的方式解释数据。

      更新

      抱歉,我没有回答你的问题。如果您的数据库有函数,您可以使用允许您传入参数并返回标量值或使用存储过程的函数。每个表达式可能有 1 个,并有一个更大的过程来以某种方式组合表达式。

      【讨论】:

      • 如果您有一个没有 UI 的 ETL 应用程序,“代码”会放在哪里?
      【解决方案4】:

      这样的事情怎么样:

      Tables:
       tags( id, name )
       goods ( id, ... )
       goods_tags_mm ( tag_id, good_id )
       rules ( id, name )
       rules_cnf ( id, rule_id )
       rules_cnf_terms ( rules_cnf_id, tag_id )
      

      【讨论】:

        【解决方案5】:

        我会用一张桌子

        tags(id,name,type,expression,order)
        
        • type 会显示标记是正常的还是经过计算的。
        • order 如果您添加新的计算标签,则会重新排序,它指定这些标签的计算顺序...
        • 表达式在插入行之前被解析和检查,它也可以使用 GUI 构建(类似于 Oracle 发现者如何做这些事情)。
        • 您只能将普通标签链接到项目

        对于您的示例,二手货需要在二手报价之前计算,所有其他的都可以在没有任何依赖关系的情况下计算。

        1,'new',1,'',NULL
        2,'for_sale',1,'',NULL
        3,'used',1,'',NULL
        4,'offer',1,'',NULL
        5,'second_hand_goods',2,'(!new or used) and for_sale',1
        6,'new_offer',2,'new and offer',1
        7,'second_hand_offer',2,'second_hand_goods and offer',2
        

        一个项目只能由 for_sale 标记,计算将给出:

        second_hand_goods,second_hand_offer
        

        我将有一个函数列出项目的所有标签,包括直接标签和计算标签:

        for_sale,second_hand_goods,second_hand_offer
        

        【讨论】:

          猜你喜欢
          • 2014-06-06
          • 1970-01-01
          • 1970-01-01
          • 2012-10-15
          • 2015-12-15
          • 1970-01-01
          • 1970-01-01
          • 2010-12-26
          • 1970-01-01
          相关资源
          最近更新 更多