代码之家  ›  专栏  ›  技术社区  ›  zarko.susnjar

用于保存随机布尔表达式的数据库模型

  •  3
  • zarko.susnjar  · 技术社区  · 14 年前

    我有这样的表达:

    (猫或猫或小猫或小猫)和(狗或狗)不是(鸽子或萤火虫)

    有人知道怎么做桌子来保存这些吗?

    在收到使用方括号的请求之前,我限制了运算符的使用,以避免出现不明确的情况。所以只有ands和nots或者ors,以这种方式保存了它们:

    算子

    id | name  
    1  | AND  
    2  | OR  
    3  | NOT  
    

    关键词

    id | keyword  
    1  | cat  
    2  | dog  
    3  | firefly  
    

    表达

    id | operator | keywordId  
    1  | 0        | 1   
    1  | 1        | 2  
    1  | 3        | 3  
    

    那是:猫和狗不是萤火虫

    但现在,我真的很困惑…

    5 回复  |  直到 14 年前
        1
  •  0
  •   Tim Schmelter    14 年前

    我认为你需要一种可能性来具体化“子表达式”。为什么不在表表达式中有一个可以为空的foreignkey链接到它本身(到父表达式)?

        2
  •  3
  •   ThiefMaster    14 年前

    将它们保存为字符串或序列化数据结构(例如,解析树)很可能是最好的解决方案,除非您确实需要修改数据库中表达式的某些部分。

        3
  •  3
  •   Ira Baxter    14 年前

    我会把它们作为 reverse Polish 在文本格式中,运算符/操作数为空,例如:

    cat cats OR dog dogs OR AND
    pigeon firefly OR NOT
    

    这使您能够真正轻松、简单地实现布尔表达式计算器,我想这就是您想要的。

    如果您想让评估更容易,我会将对象名称的绑定存储到一个小词汇表(例如,a-z)中,并为和、或、或存储类似的词汇表:

    cat A cats B dog C dogs : DAB+CD+&
    pigeon A firefly : AB+~
    

    那么,基本的表达式评估器只需要处理invidual字符,并且非常容易编写代码。

        4
  •  2
  •   Abe Miessler    14 年前

    在过去这样的情况下,我创建了一个整数列,可以对其执行逐位操作。解释如下:

    首先为每个值分配一个二进制数字-

    Cat  Dog  Firefly
    ---  ---  ------
    1     2     4
    

    接下来,您将向主表中添加一个整型列,我们称之为选项。当数字转换为二进制数字时,每个数字代表天气猫、狗或萤火虫。例子:

    5=101二进制=允许猫,不允许狗,允许萤火虫。

    id | locationName | options
    ---------------------------
    1  | loc 1        | 5
    2  | loc 2        | 2
    3  | loc 3        | 7
    4  | loc 4        | 6
    

    现在,我们可以对“选项”列使用位操作来确定允许哪些选项。实例:

    要获取所有允许狗在不涉及猫或萤火虫时使用的记录,您将执行以下按位操作:

    2个选项=2

    这将返回记录2、3和4。


    要获取所有允许狗和萤火虫的记录,我们将执行以下逐位操作:

    6个选项=6

    这将返回记录3和4


    要获取允许cats和firefly的所有记录,我们将执行以下按位操作:

    5个选项=5个

    这将返回记录1和3。


    只接受萤火虫:

    4个选项=4


    不接受萤火虫:

    4个选项=0


    这可能是一个难以理解的概念,所以如果您有任何问题,请告诉我。在我看来,一旦你掌握了这个概念,这可能是完成你正在尝试做的事情的最简单的方法。

        5
  •  0
  •   Big Endian    14 年前

    (猫或猫)和(狗或狗)不是(鸽子或萤火虫)

    猫和狗不是萤火虫

    都是无效的布尔表达式,因为not是一元运算符(它只接受1个操作数)。

    说了这句话,这是一种痛苦。很难在数据库级别进行本地化。六羟甲基三聚氰胺六甲醚。。我想到了以下几点:

    表达

    ID运算符关键字1关键字2表达式1表达式2

    这里,keyword1、keyword2、expression1和expression2都可以为空,并且每个表达式都存储为关键字或其他表达式上的一元操作,或者0、1或2关键字和0、1、2其他表达式上的二进制操作。每个表达式1条记录,所有子表达式都有附加记录。您可以递归地完成代码中的计算。

    这样就不会有重复的ID。我看到的唯一缺点是很难保存像猫和猫、狗对猫和狗这样的东西。这两种方法的计算结果相同,但计算顺序不同。

    很肯定这会奏效的。如果你需要更多的细节,请在评论中给我打电话。

    普拉门