2008-11-04 9 views
15

¿Conoce una forma de organizar las expresiones booleanas en una base de datos al tiempo que permite el anidamiento infinito de las expresiones?Modelo de datos para expresiones booleanas

Ejemplo:

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

La expresión como un todo no deben ser almacenados como varchar para preservar la integridad de datos.

+0

Por favor, aclarar: Usted ¿Desea almacenar el resultado de la expresión o ser capaz de reconstruir la expresión desde los tipos de columna de DB nativos? –

+0

Me gusta reconstruir la expresión. –

+0

¿Existe un requisito de que la base de datos sea SQL/relacional? ¿Puedes usar un OODBMS? – Oddthinking

Respuesta

8

Una expresión es una estructura treelike. Entonces necesitas una manera de presentar el árbol en una tabla.

Por ejemplo, puede utilizar los campos:

  • ID
  • TypeExpression (y, o etc ...)
  • FirstChildID
  • SecondChildID

En este caso, usted tiene los siguientes tipos:

  1. AND, Los niños apuntan a otra expresión.
  2. O, los niños apuntan a otra expresión.
  3. Igual, Los niños apuntan a otra expresión.
  4. Literal, FirstChild apunta a una entrada en una tabla literal.
  5. VariableLookup, FirstChild señala una entrada en una tabla que se puede usar.

Pero creo que hay mejores formas de organizar la expresión. Una vez hice un evaluador de expresiones simples que acepta una cadena y produce un resultado numérico.

13

La opción 1 sería utilizar una tabla anidada (un árbol con la estructura id/parent_id), como se sugirió Gamecat. Esto es relativamente costoso de hacer, y requiere emitir consultas SQL repetitivamente para construir el equivalente de una sola expresión anidada.

La opción 2 sería usar un objeto serializado y almacenarlo en una columna varchar. Por ejemplo, JSON sería una buena opción. No es sensible al espacio en blanco, se puede crear y analizar en una gran cantidad de idiomas y conserva la integridad de los datos.

Tan pronto como haya analizado el string de expresión en un objeto de árbol en la memoria, puede serializarlo y almacenarlo. Si no hubiera necesidad de manipular la expresión en el nivel de la base de datos, creo que iría por esa ruta.

+1

Está haciendo un muy buen punto aquí: uno no debería usar la opción 1 solo porque se puede usar; debe haber ciertos requisitos establecidos para justificar la opción 1. Si tales requisitos no son inminentes, probablemente comenzaría desde la opción 2. – Yarik

1

Esto será difícil de representar relacionalmente, porque por su naturaleza es tanto jerárquico como polimórfico (las hojas de su árbol pueden ser variables o constantes).

2

Este tipo de expresión generalmente se expresa como un árbol (una jerarquía), que son notoriamente molestos para consultar en SQL.

Supondremos que a y b son numéricos por el momento y que los literales ('1', '2') se distinguen de las variables.

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

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

Esta estructura es muy flexible, pero la consulta para recuperar una expresión compleja que va a ser "divertido" (leído que "desafiante").

Y todavía tiene que analizar la estructura para comenzar y evaluar la expresión después de haber sido reconstruida.

2

La forma tradicional de modelar las funciones booleanas es usar Binary Decision Diagrams, especialmente los diagramas de decisión binarios de orden reducida. Es posible que pueda encontrar una extensión para su DBMS que brinde un buen soporte para el concepto.

ACTUALIZACIÓN: Alternativamente, si no necesita consultar en la lógica booleana, puede utilizar una biblioteca BDD y simplemente serializar el BDD en un BLOB o equivalente. Es mejor usar un campo varchar porque la biblioteca BDD aseguraría que los datos fueran válidos.

0

Agregando a @Gamechat respuesta

creo que debe ser así

ID

TypeExpression (y, o etc ...)

FirstChildID --Este puede ser una nodo hoja o un puntero a otra fila en la misma tabla

SecondChildID - Esto puede ser un nodo hoja o un puntero a otra fila en la misma tabla

isFirstChildLeaf

isSecondChildLeaf

2

que almacenaría la expresión en forma de uñas, en una columna varchar/texto. Una expresión en forma pulida (operando antes de operandos, sin corchetes) es mucho más fácil de analizar con una función recursiva (o una pila de curso).

a = 1 y (b = 1 ó b = 2)

en forma de esmalte de muestra como esto:

Y = a 1 OR = b 1 = b 2

Cuestiones relacionadas