布尔表达式的数据模型

时间:2008-11-04 12:28:20

标签: database-design datamodel boolean-expression

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

示例:

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

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

8 个答案:

答案 0 :(得分:15)

选项1将使用嵌套表(具有id / parent_id结构的树),如Gamecat建议的那样。这样做相对昂贵,并且需要重复发出SQL查询以构建等效的单个嵌套表达式。

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

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

答案 1 :(得分:8)

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

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

  • ID
  • TypeExpression(和,等等......)
  • FirstChildID
  • SecondChildID

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

  1. AND,孩子指向其他表达。
  2. OR,孩子指向其他表达。
  3. Equal,Children指向其他表达。
  4. Literal,FirstChild指向文字表格中的条目。
  5. VariableLookup,FirstChild指向可变量表中的条目。
  6. 但我认为有更好的方法来组织表达。我曾经做过一个简单的表达式求值程序,它接受一个字符串并产生一个数字结果。

答案 2 :(得分: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

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

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

答案 3 :(得分:3)

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

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

波兰形式的

显示如下:

AND = a 1 OR = b 1 = b 2

答案 4 :(得分:2)

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

答案 5 :(得分:2)

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

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

答案 6 :(得分:0)

添加到@Gamechat回答

我认为应该是这样的

ID

TypeExpression(和,等等......)

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

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

isFirstChildLeaf

isSecondChildLeaf

答案 7 :(得分:0)

好的答案,但是如果一个表达式组中有两个以上的表达式怎么办?

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'和{{ 1}})
  • operation = 'EQUALS'可以是'groupeType'或'AND'
  • OR可以具有ConditionGroup的子列表最后的ConditionGroup,但不能两者。< / li>
  • 现在您的起始表达式是Condition,递归地挖掘其ConditionGroup,直到找到最终条件,然后返回值并应用正确的subConditionGroups

实际上,这就是我要尝试的。