2010-12-12 2 views
1

Я занимаюсь внедрением системы вознаграждений/достижений пользователей для веб-сайта, над которым я работал в течение прошлого года. Основная предпосылка похожа на то, что вы найдете на GameTrailers или GiantBomb.com: пользователь получает наградные значки (визуальное представление достижения) за такие вещи, как: создание [x] многих комментариев или добавление [x] многих предметов к их списку желаний и т. д.Отслеживание действий пользователей для системы вознаграждения/достижения

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

  1. Создайте каждое достижение в базе данных (это произойдет независимо). Достижение имеет категорию, номер принятия и SQL для динамического выполнения, чтобы определить, выполнено ли принятие.
  2. Всякий раз, когда пользователь выполняет действие, которое потенциально может дать достижение (например, комментарий к статье), я запускаю инструкцию SQL, чтобы определить, к каким достижениям они подходят (я фильтрую на основе категории и удаляю которые они уже выполнили).
  3. Из достижений, возвращенных в этом запросе, я просматриваю каждый и выполняю динамический SQL, чтобы определить, был ли принят номер приема. Если это так, пользователь выполнил достижение.

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

Пример выше сценария ниже (этот код не весь совершенен, просто издеваться .. Кстати, идент что-то я получить, не то, что пользователь вводит):

achievements = From ach In searchCtx.Achievements 
       Where ach.CategoryID = achievementCategoryID And ach.IsActive = 1 
       Select ach 

For Each achmt As Achievement In achievements 
    Dim achieved As Boolean 
    Dim sqlToExecute As String = qst.SQLToRun 
    sqlToExecute = sqlToExecute.Replace("@USERID", "'" + userid.ToString + "'") 
    sqlToExecute = sqlToExecute.Replace("@TARGETVAL", achmt.AcceptanceNumber) 
    achieved = searchCtx.ExecuteQuery(Of Boolean)(sqlToExecute).First 

    If achieved Then 
     ' Add Conquest to User Achievemnets 
     Dim usrAhmt As New UserAchievement 
     usrAhmt .UserID = userid 
     usrAhmt .DateCompleted = DateTime.Now 
     usrAhmt .AchievementID = achmt .ID 
     searchCtx.UserAchievements.InsertOnSubmit(usrAhmt) 
    End If 

Следующая

SqlToExecute вызывает функцию, которая возвращает логическое значение, что-то вроде:

select count(id) from comment where userid = @userID 

Так сказав все это, я думаю, что это будет работать, но я обеспокоен Performa сть. Я не слишком хорошо знаком с веб-программированием, но было бы лучше, возможно, сохранить объект UserStats в сеансе, а затем работать над этим, чтобы определить, сделал ли пользователь достаточное количество комментариев для завершения достижения? Это будет менее динамичным, но, возможно, менее напряженным на сервере SQL.

Любые предложения были бы очень признательны !!

ответ

0

Это зависит от количества действий пользователей, которые у вас есть. Если у вас мало (скажем, менее 10 тыс. В день), у вас есть прекрасный способ, оставьте это.

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

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

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