Система достижений / значков - PullRequest
29 голосов
/ 16 ноября 2009

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

В PHP и MySQL было бы ясно, что некоторые достижения зарабатываются немедленно (когда выполняется специальное действие, в случае SO: заполняются все поля профиля), хотя я знаю, что SO обновляет и назначает значки через определенное время , При таком количестве пользователей и значков это не вызовет проблем с производительностью (с точки зрения масштаба: большое количество пользователей и значков).

Итак, я предполагаю, что структура базы данных будет такой простой:

Badges     |    Badges_User      |    User
----------------------------------------------
bd_id      |    bd_id            |  user_id
bd_name    |    user_id          |  etc
bd_desc    |    assigned(bool)   |  
           |    assigned_at      |

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

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

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

РЕДАКТИРОВАТЬ: к некоторому сглаживанию некоторой путаницы, которую я назначил_at как Дата / Время, критерии для присвоения значка лучше всего поместить в подготовленные запросы / функции для каждого значка, не так ли? (лучшая гибкость)

Ответы [ 4 ]

7 голосов
/ 17 ноября 2009

Я бы сохранил структуру типа, аналогичную той, что у вас есть

Badges(badge_id, badge_name, badge_desc)
Users(user_id, etc)
UserBadges(badge_id, user_id, date_awarded)

А затем добавьте таблицы отслеживания в зависимости от того, что вы хотите отслеживать и @ какого уровня детализации ... тогда вы можете соответствующим образом обновить таблицу и установить триггеры для нее, чтобы "награждать" значки

User_Activity(user_id, posts, upvotes, downvotes, etc...)

Вы также можете отслеживать статистику в другом направлении и получать награды за значки

Posts(post_id, user_id, upvotes, downvotes, etc...)


Некоторые другие хорошие замечания сделаны здесь
7 голосов
/ 17 ноября 2009

Я думаю, что предложенная вами структура (без «назначенного» поля в соответствии с комментариями) будет работать, с добавлением дополнительной таблицы, скажем «Submissions_User», содержащей ссылку на user_id и увеличивающееся поле для подсчета Доводы. Тогда все, что вам нужно, это «прослушиватель событий» в соответствии с этим постом и метинкс, который вам нужно установить.

РЕДАКТИРОВАТЬ: Для значков достижений запускайте прослушиватель событий при каждой отправке (только для пользователя, выполняющего отправку курса) и присваивайте любой соответствующий значок на месте. Для значков, основанных на времени, я каждую ночь выполнял работу CRON. Пройдите один раз по всему списку пользователей и присвойте значки в зависимости от ситуации.

7 голосов
/ 16 ноября 2009

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

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

4 голосов
/ 17 ноября 2009

Я думаю, что это один из тех случаев, когда подходит таблица «многие ко многим» (Badges_User). Но с небольшим изменением, чтобы неназначенные значки не сохранялись.

Я предполагаю, что assigned_at - это дата и / или время.
По умолчанию у пользователя нет значков.

Badges     |    Badges_User      |  User
----------------------------------------------
bd_id      |    bd_id            |  user_id
bd_name    |    user_id          |  etc
bd_desc    |    assigned_at      |  
           |                     |

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

Привет
Sigersted

...