Модель базы данных для сохранения случайных логических выражений - PullRequest
3 голосов
/ 20 мая 2010

У меня есть такие выражения:

(кошка ИЛИ кошка ИЛИ котенок ИЛИ котенок) И (собака ИЛИ собака) НЕ (голубь ИЛИ светлячок)

У кого-нибудь есть идеи, как создавать таблицы для их сохранения?

Прежде чем я получил запрос на использование скобок, я ограничил использование операторов, чтобы избежать неоднозначных ситуаций. Таким образом, только AND и NOT или только OR и сохранили их таким образом:

операторы

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 ]

3 голосов
/ 20 мая 2010

Я бы сохранил их как обратный польский в текстовом формате с операторами / операндами через пробелы, для ваших примеров:

cat cats OR dog dogs OR AND
pigeon firefly OR NOT

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

Если бы вы хотели сделать оценку еще проще, я бы сохранил привязки имен объектов к небольшому словарю (например, A-Z) и аналогичному словарю для AND, OR, NOT:

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

Тогда базовый оценщик выражений должен работать только с отдельными символами и его действительно очень легко кодировать.

3 голосов
/ 20 мая 2010

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

2 голосов
/ 20 мая 2010

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

Начните с присвоения одной двоичной цифры каждому значению-

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

Далее вы добавите целочисленный столбец в основную таблицу, мы назовем его options. Когда число преобразуется в двоичное, каждая цифра будет обозначать погоду кошек, собак или светлячков. Пример:

5 = 101 в двоичном виде = кошки разрешены, собаки запрещены, светлячки разрешены.

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

Теперь мы можем использовать побитовые операции со столбцом параметров, чтобы определить, какие параметры разрешены. Примеры:

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

2 & options = 2

Это вернет записи 2,3 и 4.


Чтобы получить все записи, которые разрешают собак и светлячков, мы выполним следующую побитовую операцию:

6 & options = 6

Это вернет записи 3 и 4


Чтобы получить все записи, которые позволяют кошкам и светлячкам, мы выполним следующую побитовую операцию:

5 & options = 5

Это вернет записи 1 и 3.


ТОЛЬКО принимает светлячков:

4 | Варианты = 4


Не принимает светлячков:

4 & options = 0


Вероятно, это сложная концепция, поэтому, пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы. Мне кажется, что это может быть самый простой способ выполнить то, что вы пытаетесь сделать, когда вы сможете понять концепцию.

0 голосов
/ 20 мая 2010

(кошка ИЛИ кошки) И (собака ИЛИ собаки) НЕ (голубь ИЛИ светлячок)

и

кошка и собака НЕ ​​светлячок

Являются ли недопустимыми логическими выражениями, поскольку NOT является унарным оператором (он принимает только 1 операнд).

Сказав это, это крепкий орешек. Достаточно сложно выполнить локализацию на уровне базы данных. Хммм .. На ум приходит следующее:

Выражения

Id | Оператор | Ключевое слово 1 | слово 2 | Выражение1 | Выражение2

Таким образом, здесь ключевое слово1, ключевое слово2, выражение1 и выражение2 все обнуляются, и каждое выражение хранится либо в виде унарной операции над ключевым словом, либо другого выражения, либо в виде двоичной операции с 0, 1 или 2 ключевыми словами и 0, 1, 2 других выражения. 1 запись на выражение, с дополнительными записями для всех подвыражений. Вы можете сделать рекурсивную оценку в коде.

Таким образом, у вас не будет дубликатов. Единственный недостаток, который я вижу, заключается в том, что было бы трудно сохранить такие вещи, как (кошка и кошка) и собака против кошки и (кошки и собака). Оба они оценивают одинаково, но порядок вычислений изменяется.

Уверен, это сработает. Напишите мне в комментариях, если вам нужно больше деталей.

Пламен

0 голосов
/ 20 мая 2010

Я думаю, вам нужна возможность объединить "подвыражения". Почему бы не иметь обнуляемый внешний ключ в табличных выражениях, ссылающийся на себя (на родительское выражение)?

...