私は、過去 1 年間取り組んできた Web サイトのユーザー アワード/アチーブメント システムを実装している最中です。基本的な前提は、GameTrailers または GiantBomb.com で見られるものと似ています。ユーザーは、[x] 個のコメントを作成する、または [x] 個のアイテムを追加するなどのことを行うと、アワード バッジ (成果を視覚的に表したもの) を取得します。ウィッシュリストなどに
これを実装する最も効率的な方法を決定しようとしていますが、少し行き詰まっています。私の現在の解決策は次のとおりです。
- データベースに各実績を作成します (これは関係なく発生します)。実績には、カテゴリ、承認番号、および承認が満たされているかどうかを判断するために動的に実行する SQL があります。
- ユーザーがアチーブメントをもたらす可能性のあるアクション (記事へのコメントなど) を実行するたびに、SQL ステートメントを実行して、対象となるアチーブメントを判断します (カテゴリに基づいてフィルタリングし、対象となるアチーブメントを削除します)。すでに完了しています)。
- そのクエリで返された実績から、それぞれを調べて動的 SQL を実行し、受け入れ数が満たされているかどうかを判断します。そうであれば、ユーザーはアチーブメントを完了しました。
ステップ 2 と 3 は、ユーザーがコメントを作成するたびにこれらのクエリを実行するため、私の懸念がある場所です。
上記のシナリオの例を以下に示します (このコードは完全ではなく、ただのモックです。ところで、userid はユーザーが入力するものではなく、私が取得するものです):
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
以上のことから、これでうまくいくと思いますが、パフォーマンスが心配です。私は Web プログラミングにあまり詳しくありませんが、おそらく UserStats オブジェクトをセッションに保持し、それを操作して、ユーザーが実績を完了するのに十分なコメントをしたかどうかを判断する方がよいでしょうか? これは動的ではありませんが、SQL サーバーへのストレスが少なくなる可能性があります。
どんな提案でも大歓迎です!!