Модель данных для булевых выражений

Знаете ли вы способ организации булевых выражений в базе данных, позволяя бесконечное вложение выражений?

Пример:

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

Выражение в целом не должно храниться как varchar для сохранения целостности данных.

Ответы

Ответ 1

Вариант 1 должен был бы использовать вложенную таблицу (дерево с структурой id/parent_id), как предположил Gamecat. Это относительно дорого, и требует повторения запросов SQL для создания эквивалента одного вложенного выражения.

Вариант 2 - использовать сериализованный объект и хранить его в столбце varchar. Например, JSON будет хорошим выбором. Он не чувствителен к белому пространству, может быть создан и проанализирован на огромном количестве языков, и он сохраняет целостность данных.

Как только вы проанализировали свою строку выражений в объект дерева в памяти, вы можете сериализовать ее и сохранить. Если бы не было необходимости манипулировать выражением на уровне базы данных, я предполагаю, что я поеду по этому маршруту.

Ответ 2

Выражение является древовидной структурой. Таким образом, вам нужен способ представить дерево в таблице.

Вы можете, например, использовать поля:

  • ID
  • TypeExpression (и, и т.д.)
  • FirstChildID
  • SecondChildID

В этом случае у вас есть следующие типы:

  • И, дети указывают на другое выражение.
  • ИЛИ, Дети указывают на другое выражение.
  • Равно, дети указывают на другое выражение.
  • Literal, FirstChild указывает на запись в литеральной таблице.
  • VariableLookup, FirstChild указывает на запись в таблице переменных.

Но я думаю, что есть лучшие способы организовать выражение. Я однажды сделал простой оценщик выражения, который принимает строку и производит числовой результат.

Ответ 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

Эта структура очень гибкая, но запрос ее на получение сложного выражения будет "забавным" (читайте, что "сложно" ).

И вам еще нужно проанализировать структуру, чтобы начать и оценить выражение после его восстановления.

Ответ 4

Традиционным способом моделирования булевых функций является использование Двоичные схемы принятия решений, особенно схемы двоичного преобразования с сокращенным порядком. Возможно, вы можете найти расширение для своей СУБД, которое обеспечивает хорошую поддержку концепции.

UPDATE: В качестве альтернативы, если вам не нужно запрашивать логическую логику, вы можете использовать библиотеку BDD и просто сериализовать BDD в BLOB или эквивалент. Он бьет с использованием поля varchar, потому что библиотека BDD обеспечит достоверность данных.

Ответ 5

Я бы сохранил выражение в польский форме в столбце varchar/text. Выражение в польской форме (операнд перед операндами, без скобок) намного проще анализировать с помощью рекурсивной функции (или, конечно, стека).

a = 1 AND (b = 1 ИЛИ b = 2)

в польской форме выглядит следующим образом:

AND = a 1 OR = b 1 = b 2

Ответ 6

Это будет сложно представить реляционно, потому что по своей природе он является как иерархическим, так и полиморфным (листья вашего дерева могут быть либо переменными, либо константами).

Ответ 7

Добавление в ответ @Gamechat

Я думаю, что это должно быть так.

ID

TypeExpression (и, или и т.д.)

FirstChildID - это может быть лист node или указатель на другую строку в той же таблице

SecondChildID. Это может быть лист node или указатель на другую строку в той же таблице

isFirstChildLeaf

isSecondChildLeaf