Какова подходящая структура данных и схема базы данных для хранения логических правил?

StackOverflow https://stackoverflow.com/questions/1902951

Вопрос

Предисловие:У меня нет опыта работы с механизмами правил, построения правил, моделирования правил, реализации структур данных для правил и т. д.Поэтому я не знаю, что делаю, и не является ли то, что я пытался сделать ниже, неправильным.

Я пытаюсь понять, как хранить и обрабатывать следующий гипотетический сценарий.Чтобы упростить мою проблему, предположим, что у меня есть тип игры, в которой пользователь покупает объект, где возможных объектов могут быть тысячи, и объекты должны быть приобретены в указанной последовательности и только в определенных группах.Например, предположим, что я пользователь и хочу приобрести объект F.Прежде чем я смогу приобрести объект F, я должен предварительно приобрести объект A ИЛИ (B И C).Я не могу одновременно купить F и A, а также F и B,C.Они должны быть в той последовательности, которая указана в правиле.Сначала А, потом F.Или сначала B, C, а потом F.Меня сейчас не волнует промежуток времени между покупками или какие-либо другие характеристики пользователя, просто на данный момент это правильная последовательность.

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

Я пытался это сделать, но застрял в попытках реализовать такие группы, как A OR (B И C).Я хотел бы сохранить правила в базе данных, где у меня есть эти таблицы:

 Objects
    (ID(int),Description(char)) 

ObjectPurchRules
    (ObjectID(int),ReqirementObjectID(int),OperatorRule(char),Sequence(int)) 

Но очевидно, что, обрабатывая результаты без группировки, вы получаете неправильный ответ.Я бы хотел избежать чрезмерного анализа строк, если это возможно :).Один объект может иметь неизвестное количество предыдущих необходимых покупок.Будут признательны фрагменты SQL или псевдокода для обработки правил.:)

Это было полезно?

Решение

Похоже, ваша проблема сводится к проверке того, выполнено ли определенное условие.

У вас будут сложные условия.Итак, дана таблица элементов:

ID_Item    Description
----------------------
1          A         
2          B         
3          C         
4          F         

и дана таблица возможных действий:

ID_Action  VerbID  ItemID    ConditionID
----------------------------------------
1          BUY     4         1

Построим таблицу условий:

ID_Condition  VerbA  ObjectA_ID  Boolean  VerbB            ObjectB_ID
---------------------------------------------------------------------
1             OWNS   1           OR       MEETS_CONDITION  2
2             OWNS   2           AND      OWNS             3

Таким образом, OWNS означает, что идентификатор является ключом к таблице Items, а METS_CONDITION означает, что идентификатор является ключом к таблице Conditions.

Это не предназначено для того, чтобы ограничивать вас.Вы можете добавить другие таблицы с квестами или чем-то еще, а также добавить дополнительные глаголы, которые подскажут вам, где искать.Или просто поместите квесты в таблицу «Предметы» после их завершения, а затем интерпретируйте выполненный квест как обладание определенным значком.Тогда вы сможете обрабатывать как предметы, так и квесты с помощью одного и того же кода.

Другие советы

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

Возможно, вы захотите взять пару книг по этой теме и изучить возможность использования LUA в качестве обработчика правил.

Лично я бы сделал это в коде, а не в SQL.Каждый элемент должен быть отдельным классом, реализующим интерфейс (т.IIпункт).У IItem будет метод OkToPurchase, который будет определять, можно ли купить этот предмет.Для этого он будет использовать один или несколько наборов правил (т.HasPreviilyPurchased(x), CurrentOwns(x) и т. д.), которые вы можете построить.

Приятно то, что этот подход легко расширить новыми правилами, не нарушая при этом всю существующую логику.

Вот некоторый псевдокод:

bool OkToPurchase()
{
   if( HasPreviouslyPurchased('x') && !CurrentlyOwns('y') )
       return true;
   else
       return false;
}

bool HasPreviouslyPurchased( item )
{
    return purchases.contains( item )
}

bool CurrentlyOwns( item )
{
    return user.Items.contains( item )
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top