Модель данных для булевых выражений
Знаете ли вы способ организации булевых выражений в базе данных, позволяя бесконечное вложение выражений?
Пример:
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