Я нахожусь в процессе внедрения системы наград / достижений пользователей для веб-сайта, над которым я работал в течение прошлого года. Основная предпосылка аналогична той, что вы найдете на GameTrailers или GiantBomb.com: пользователь получает наградные значки (визуальное представление достижений) за такие вещи, как: создание [x] множества комментариев или добавление [x] множества элементов в их список пожеланий и т. д.
Я пытаюсь определить наиболее эффективный способ реализации этого, и я немного застрял. Мое текущее решение:
- Создайте каждое достижение в базе данных (это будет происходить независимо). Достижение имеет категорию, номер принятия и SQL для динамического выполнения, чтобы определить, была ли достигнута приемлемость.
- Всякий раз, когда пользователь выполняет действие, которое потенциально может привести к достижению (например, сделать комментарий к статье), я запускаю инструкцию SQL, чтобы определить, на какие достижения он имеет право (я фильтрую по категории и удаляю те, которые они уже завершили).
- Из достижений, возвращенных в этом запросе, я перебираю каждое из них и выполняю динамический 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
Итак, сказав все это, я думаю, что это сработает, но я беспокоюсь о производительности. Я не слишком знаком с веб-программированием, но было бы лучше, возможно, сохранить объект UserStats в сеансе, а затем оперировать им, чтобы определить, сделал ли пользователь достаточно комментариев для завершения достижения? Это было бы менее динамично, но, возможно, менее напряженно для сервера SQL.
Любые предложения будут высоко оценены !!