您是否知道在数据库中组织布尔表达式的方法,同时允许表达式的无限嵌套?
示例:
a = 1 AND (b = 1 OR b = 2)
整个表达式不应存储为varchar以保持数据完整性。
答案 0 :(得分:15)
选项1将使用嵌套表(具有id / parent_id结构的树),如Gamecat建议的那样。这样做相对昂贵,并且需要重复发出SQL查询以构建等效的单个嵌套表达式。
选项2是使用序列化对象并将其存储到varchar列中。例如,JSON将是一个不错的选择。它不是对空白敏感的,可以用大量语言创建和解析,并保持数据完整性。
只要将表达式字符串解析为内存中的树对象,就可以将其序列化并存储。如果不需要在数据库级别上操作表达式,我想我会走那条路。
答案 1 :(得分:8)
表达式是一种树状结构。所以你需要一种方法在表格中呈现树。
例如,您可以使用以下字段:
在这种情况下,您有以下类型:
但我认为有更好的方法来组织表达。我曾经做过一个简单的表达式求值程序,它接受一个字符串并产生一个数字结果。
答案 2 :(得分:3)
这种类型的表达式通常表示为树(层次结构),这在SQL中查询时非常烦人。
我们假设a
和b
目前是数字,文字('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
-------------------
value1
,value2
和operation
为最终比较建模,例如“ b = 3
”(在我的情况下为value1 = 'b'
,value2 = '3'
和{{ 1}})operation = 'EQUALS'
可以是'groupeType
'或'AND
'OR
可以具有ConditionGroup
的子列表或最后的ConditionGroup
,但不能两者。< / li>
Condition
,递归地挖掘其ConditionGroup
,直到找到最终条件,然后返回值并应用正确的subConditionGroups
。实际上,这就是我要尝试的。