布尔表达式的数据模型

Posted

技术标签:

【中文标题】布尔表达式的数据模型【英文标题】:Data Model for Boolean Expressions 【发布时间】:2010-09-20 16:13:05 【问题描述】:

您知道一种在数据库中组织布尔表达式同时允许表达式无限嵌套的方法吗?

例子:

a = 1 AND (b = 1 OR b = 2)

不应将整个表达式存储为 varchar 以保持数据完整性。

【问题讨论】:

请澄清:您想存储表达式的结果还是能够从本地 DB 列类型重建表达式? 我喜欢重构表达式。 是否要求数据库是 SQL/关系型?你可以使用 OODBMS 吗? 不,数据库必须是关系型的。 另见cs.stackexchange.com/questions/104311/… 【参考方案1】:

选项 1 是使用嵌套表(具有 id / parent_id 结构的树),就像 Gamecat 建议的那样。这样做的成本相对较高,并且需要重复发出 SQL 查询来构建等效的单个嵌套表达式。

选项 2 是使用序列化对象并将其存储到 varchar 列中。例如,JSON 将是一个不错的选择。它对空格不敏感,可以用多种语言创建和解析,并且保持数据完整性。

一旦您将表达式字符串解析为内存中的树对象,您就可以对其进行序列化并存储它。如果不需要在数据库级别操作表达式,我想我会走那条路。

【讨论】:

您在这里提出了一个很好的观点:不应该仅仅因为可以使用选项1而使用它;必须有某些要求来证明选项 1 的合理性。如果这些要求不是迫在眉睫,我可能会从选项 2 开始。【参考方案2】:

表达式是一个树状结构。所以你需要一种在表格中呈现树的方法。

例如,您可以使用以下字段:

身份证 TypeExpression (and, or etc...) FirstChildID SecondChildID

在这种情况下,您有以下类型:

    AND,子项指向其他表达式。 OR,子项指向其他表达式。 相等,子项指向其他表达式。 文字,FirstChild 指向文字表中的条目。 VariableLookup,FirstChild 指向变量表中的条目。

但我认为有更好的方式来组织表达。我曾经做过一个简单的表达式求值器,它接受一个字符串并产生一个数字结果。

【讨论】:

【参考方案3】:

这种类型的表达式通常表示为树(层次结构),众所周知,在 SQL 中查询很烦人。

我们暂时假设 ab 是数字,并且文字('1','2')与变量区分开来。

Table Nodes
id
type (Variable|Literal)
name (nullable for literal)
value

Table Operators
id
name (=, AND, OR, NOT)
leftNodeId
rightNodeId

这种结构非常灵活,但查询它以检索复杂的表达式会很“有趣”(读作“具有挑战性”)。

你仍然需要解析结构,并在重建后评估表达式。

【讨论】:

【参考方案4】:

我会将表达式以波兰语形式存储在 varchar/text 列中。波兰语形式的表达式(操作数在操作数之前,没有括号)更容易使用递归函数(或当然是堆栈)进行解析。

a = 1 AND (b = 1 OR b = 2)

波兰语形式如下:

AND = a 1 OR = b 1 = b 2

【讨论】:

【参考方案5】:

这将很难以关系表示,因为它的本质是分层和多态的(树的叶子可以是变量或常量)。

【讨论】:

【参考方案6】:

对布尔函数建模的传统方法是使用Binary Decision Diagrams,尤其是降阶二元决策图。您可能会找到为您的 DBMS 提供良好支持的扩展。

更新: 或者,如果您不需要查询布尔逻辑,您可以使用 BDD 库并将 BDD 序列化为 BLOB 或等效项。它优于使用 varchar 字段,因为 BDD 库将确保数据有效。

【讨论】:

【参考方案7】:

答案没问题,但如果表达式组中有超过 2 个表达式怎么办?

a = 1 AND (b = 1 OR b = 2 OR b = 3)

我建议这样做:

-------------------
|    Condition    |
-------------------
| - id            |
| - value1        |
| - value2        |
| - operation     |
-------------------
    |(1)
    |        --------------
    |       |              |
    |       |(*)           |
-------------------        |
| ConditionGroup  |        |
-------------------        |
| - id            |--------
| - groupType     |
| - condition     |
| - subConditionGroups
-------------------
value1value2operation 模拟最终比较,如“b = 3”(在我的情况下为 value1 = 'b'value2 = '3'operation = 'EQUALS'groupeType 可以是“AND”或“ORConditionGroup 可以有ConditionGroups 的子列表最终的Condition,但不能同时拥有。 现在您的起始表达式是ConditionGroup,递归地挖掘它的subConditionGroups,直到找到最终条件,然后返回值并应用正确的condition

其实这就是我要尝试的。

【讨论】:

【参考方案8】:

添加到@Gamechat 答案

我觉得应该是这样的

身份证

TypeExpression (and, or etc...)

FirstChildID -- 这可以是叶节点或指向同一表中另一行的指针

SecondChildID --这可以是叶节点或指向同一表中另一行的指针

isFirstChildLeaf

isSecondChildLeaf

【讨论】:

以上是关于布尔表达式的数据模型的主要内容,如果未能解决你的问题,请参考以下文章

使用数据注释强制模型的布尔值为真

如何使用数据注释为模型属性 WebApi .NET Core 添加布尔验证

组件与模板 显示数据

DOMWindow对象操作

如何在 Code First 模型中的布尔值上设置默认值?

在实体框架中将模型属性设置为布尔值