14

如何使用 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 轻松访问的模式将是可取的。
  • 最好可以在一次选择/调用中检索整个规则?

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

提前致谢。

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

4

5 回答 5

6

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

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

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

于 2009-02-13T11:44:25.157 回答
5

管理嵌套/括号会变得非常复杂并且容易出错。我过去这样做的方法是使用 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>

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

于 2009-02-13T11:33:03.407 回答
1

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

更新

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

于 2009-02-13T11:29:24.400 回答
0

我会用一张桌子

tags(id,name,type,expression,order)
  • type将显示标签是正常的还是计算的。
  • 如果您添加新的计算标签,订单将重新排序,它指定这些标签的计算顺序...
  • 在插入行之前解析和检查表达式,它也可以使用 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
于 2009-03-10T07:51:20.053 回答
0

像这样的东西怎么样:

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 )
于 2009-02-13T14:16:20.753 回答