Подтвердить что ты не робот

Архитектура базы данных для системы "Значки" и произвольных критериев (MySQL/PHP)

Недоброкачественная-Вопрос:

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

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

  • badge_id (1)
  • badge_title (значок 10K)
  • badge_image (10k.jpg)
  • badge_criteria ([posts] >= 10000)
    ...

наматывается-Вопрос:

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

Значки, которые основаны на пользовательских точках (Гипотетический "Значок 10k" ), выглядят довольно прямолинейно. Любое событие, которое влияет на репутацию пользователей (upvotes, downvotes, answer-accepted и т.д.), Будет ссылаться на метод обзора новой репутации пользователей и потенциально награждать значок.

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

Пользовательская репутация, вероятно, является значением внутри самой пользовательской записи. Но в идеале, не хотите ли вы не добавлять новые поля в таблицу пользователей при создании новых значков? Например, значок "Edited 100 Entries" - вы не создали бы новый столбец "entries_edited" в таблице Users, не так ли? А затем увеличивайте, что после каждой редактируемой записи...

Любые подсказки?

Архив Stackoverflow:


Примечание. Я НЕ спрашиваю, как связать значки с пользователями. Я не спрашиваю, как награждать значки (это будет сделано программно)

4b9b3361

Ответ 1

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

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

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

В качестве альтернативы вы можете использовать какой-то DSL для написания своих "правил", но в итоге вы также должны создать парсер для анализа правил при их чтении, а также для выполнения этих правил. В зависимости от сложности, которую вы хотите использовать в DSL, это может быть не тривиальная задача. Это похоже на путь, который вы задаете в своем вопросе, имея столбец Criteria (предположительно простой текст), который имеет что-то вроде "[Репутация] > 1000" или "[Сообщений] > 5". Вы все равно должны разбирать и выполнять эти правила, и сложность написания чего-то для этого зависит от того, насколько сложны эти правила.

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

Ответ 2

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

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)
...

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

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

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

Ответ 3

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

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

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
)

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

Я не спрашиваю, как награждать значки. Я спрашиваю, как хранить критерии в базе данных.

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

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

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

Таким образом, это будет в вашем поле критериев:

select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000

Ответ 4

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

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

Ответ 5

Извиняюсь за то, что я краток.

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

badge_criteria
badge_key int
badge_criteria varchar(max)

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

Ответ 6

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

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

Ответ 7

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

Обновление:

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

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