Вопрос по – Архитектура базы данных для системы «Badge» и произвольные критерии (MySQL / PHP)

47

Quickie-Question:

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

Сохранение названия значка, критериев и т. Д. Как будет выглядеть эта таблица?

  • badge_id (1)
  • badge_title (10K Badge)
  • badge_image (10k.jpg)
  • badge_criteria ([posts] >= 10000)
    ...

Winded-Question:

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

Значки, основанные на пользовательских баллах («Гипотетический», значок 10 тыс.), Могут показаться довольно простыми. Любое событие, которое влияет на репутацию пользователя (положительные, отрицательные, принятые ответы и т. Д.), Будет вызывать метод проверки новой репутации пользователей и потенциального присвоения значка.

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

Репутация пользователя, вероятно, является значением в самой записи пользователя. Но в идеале, не хотите ли вы избегать добавления новых полей в пользовательскую таблицу при создании новых значков? Например, «Отредактировано 100 записей» значок - вы не будете создавать новый столбец "records_edited" в таблице пользователей, не так ли? И затем увеличивать это после каждой записи редактировать ...

Есть намеки?

Архив Stackoverflow:


Note: I'm NOT asking how to associate badges with users. I'm NOT asking how to award badges (that will be done programmatically)

@ Джонатан Сэмпсон Не могли бы вы поделиться своим последним ответом: 1) В какой методологии вы пришли к выводу? 2) Уроки, извлеченные из вашей методологии. С уважением и спасибо за этот чудесно заданный вопрос. Andre Chenier
@JasonDavis я не сделал. Если бы я делал это сегодня, у меня, вероятно, была бы серия сценариев (каждый из которых представлял один значок / достижение), которые выполнялись бы на регулярной основе. Серия внешних сценариев кажется мне наиболее гибким решением, поскольку оно допускает сверхтонкие, специальные условия. Sampson
+1, так как я ищу тот же ответ. Robert S.
Сэмпсон Мне также любопытно, когда ты когда-нибудь заканчивал свой проект и имел что-нибудь полезное, чем ты мог бы поделиться? Я нашел ваш пост, поскольку у меня была та же идея сохранить критерии для значка в таблице значков. Я все еще исследую лучший способ сделать мою систему, хотел бы услышать от любого, кто сделал это! Спасибо JasonDavis

Ваш Ответ

7   ответов
3

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

С помощью этого метода требования к значкам также могут быть связаны вместе, чтобы сформировать более сложные зависимости. Например, чтобы получить этот значок, пользователь должен получить три отдельных значка с определенными временными рамками.

23

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

Если вы заранее знаете, что хотите, чтобы значки были ограничены только определенными полями (то есть значки основаны только на репутации или количестве правок или чего-то еще), вы можете сохранить их в простой таблице, например:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

В качестве альтернативы вы могли бы использовать какой-либо DSL для написания своих «правил». но в конечном итоге вам также необходимо создать синтаксический анализатор для анализа правил при их чтении, а также что-то для выполнения этих правил. В зависимости от сложности вашей DSL, это может быть не тривиальной задачей. Это похоже на путь, по которому вы идете в своем вопросе, имея столбец Критерии (предположительно простой текст), который имеет что-то вроде & quot; [Репутация] & gt; Тысяча & Quot; или & quot; [Сообщения] & gt; 5 & Quot; в этом. Вам все еще нужно разобрать и выполнить эти правила, и сложность написания чего-либо зависит от того, насколько сложными должны быть эти правила.

Я бы порекомендовал вам прочитатьэти Ежедневно WTFстатьи для получения информации о том, почему этот подход приводит к боли.

Спасибо. Вы, кажется, первый человек, который действительно понял мой вопрос;) Sampson
3

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

badge_criteria
badge_key int
badge_criteria varchar(max)

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

5

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

Пользователь может иметь много значков, а значок может иметь много пользователей.

create table users (
id int,
name varchar
)

create table badges (
id int,
badge_name varchar
)


create table user_badges_xref (
user_id int,
badge_id int
)

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

I'm not asking how to award badges. I'm asking how to store criteria within the database.

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

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

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

Так что такого рода вещи будут в вашем поле критериев:

select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000
Я не спрашиваю, как связать значки с пользователями, я спрашиваю, как создать и сохранить критерии для значков в будущем. Sampson
Я не спрашиваю, как награждать значки. Я спрашиваю, как хранить критерии в базе данных. Sampson
+1 за объединяющий стол
3

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

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

2

и должно быть сделано в вашей бизнес-логике в приложении. Таким образом, у вас есть все существующие данные, которые вам нужны (изменения, посещения, репутация и т. Д.), И с ними можно обращаться по своему усмотрению.

Update:

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

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

Сейчас я пытаюсь создать систему бейджей, и у меня была одна идея - возможно, сохранить метод класса в моей таблице бейджей, который бы обрабатывал логику для этого бейджа. Есть какие-нибудь мысли о его?
Да, я награждаю значок кодом. Но критерии для значка в идеале будут храниться в базе данных, если я не ошибаюсь. Sampson
Я никогда не думал о конфигурационном файле, но это может сработать. Я больше думал о том, как хранить константы в «Бейдже». класс - что по сути одно и то же. Это действительно зависит от того PHP-фреймворка, который вы используете.
Значит, Badge-Criteria должен храниться в конфигурационном файле? Или что? То, чего я пытаюсь избежать, - это необходимость вводить реальную логику для добавления нового значка. Sampson
19

как далеко вы хотите зайти, ваша схема может быть довольно сложной. Мне кажется, что базовые элементы, которые нужно отслеживать:

Badges awarded
Points earned

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

Point categories
Badge categories

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

badges:
badge_id
badge_name
required_points
....

point_categories:
point_id
category_name
weighting (optional)
...

point_groups:
badge_id
point_id
weighting (optional)
...

user_points:
user_id
point_id
points
...

user_badges:
user_id
badge_id
points_earned
badge_awarded (yes/no)
...

Ваш & quot; администратор & quot; Интерфейс позволит кому-то создать новый значок и выбрать, какие категории баллов необходимы для получения этого значка (point_groups). Всякий раз, когда пользователь зарабатывает очки (user_points), вы обновляете таблицу user_points, а затем определяете, на какие значки эти баллы могут быть внесены (point_groups). Затем вы перекомпилируете баллы для значков, на которые повлияли заработанные баллы, и обновите таблицу user_badges с помощью point_earned. Затем проверьте поле points_earned в user_badges с обязательными точками в таблице значков.

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

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

+1 Это лучший ответ. Это наиболее продуманно и подробно объяснено.
Это работает в простом случае, когда значки строго основаны на достижении некоторого количества пунктов, которые ОП специально назвал прямыми в вопросе. Реальный вопрос заключается в том, как вы делаете это для «неисчислимых» количество значков, которые не являются простыми, у пользователя есть & gt; X баллов & quot; типа из них.
Привет, вы можете записать простой запрос для проверки таблицы выше?
Я не могу понять, почему этот ответ не является общепринятым и одобренным. Я часами думаю, чего не вижу, что видели другие люди. Для меня это лучшая логика, но многие гуру знают лучше меня :-(
проголосовал за много печатать. Кроме того, я думаю, что это правильный путь, чтобы идти вниз ... хотя, как далеко вы идете по этому пути, до вас.

Похожие вопросы