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

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

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

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

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

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

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

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

Ответы [ 3 ]

5 голосов
/ 14 декабря 2009

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

У вас будут сложные условия. Так дана таблица предметов:

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 означает, что идентификатор является ключом к таблице Предметов, а MEETS_CONDITION означает, что идентификатор является ключом к таблице Условий.

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

0 голосов
/ 14 декабря 2009

Лично я бы сделал это в коде, а не в SQL. Каждый элемент должен быть своим собственным классом, реализующим интерфейс (т.е. IItem). У IItem будет метод OkToPurchase, который будет определять, можно ли покупать этот товар. Для этого он будет использовать одно или несколько наборов правил (например, HasPreviouslyPurchased (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 )
}
0 голосов
/ 14 декабря 2009

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

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

...