StackExchange のバッジの仕組みと非常によく似たバッジ システムを構築しています。個々のバッジの適格性を照会するには、テーブル内に SQL クエリを配置して、cron ジョブの一部として実行できるようにするのが最適なソリューションのようです。
使用を考えているクエリスタイルは次のとおりです。
SELECT u.user_id
FROM users u
WHERE (
SELECT COUNT(*)
FROM comments c
WHERE c.user_id = u.user_id
) > 0
AND [$badge_id] NOT IN (
SELECT b.badge_id
FROM user_badges b
WHERE b.user_id = u.user_id
)
テーブルは次のようになります。
badge_id | name | description | level | hash | query
---------+-----------------+---------------+-------+-----------------------------------------------------------------------------------------------------------------
1 | Hello World | First comment | 1 | 50a7c570f... | u.user_id FROM users u WHERE ( SELECT COUNT(*) FROM comments c WHERE c.user_id = u.user_id ) > 0
2 | Into the Breach | First thread | 1 | 6b01e9348... | u.user_id FROM users u WHERE ( SELECT COUNT(*) FROM threads t WHERE t.user_id = u.user_id ) > 0
クエリはデータベースから取得され、接頭辞が付けられSELECT
、AND [$badge_id] NOT IN (...)
サブクエリ条件が追加されます。[$badge_id]
その後、現在のバッジ IDに置き換えられます。クエリが実行され、バッジを付与する必要があるユーザー ID のリストが返されます。
ハッシュ フィールドは、PHP スクリプトで定義されたキーを使用して、クエリの HMAC-SHA1 ハッシュを格納するために使用されます。この背後にある考え方は、SQL インジェクション攻撃が発生した場合でも、攻撃者はスクリプト内のキーにアクセスできず、より危険なクエリを偽造できないというものです。
2 つの質問があります。
- テーブル内の SQL は本当に悪い方法ですか? もしそうなら、なぜですか?私は代替案を受け入れます。
- 同じクエリを達成するためのより効率的なクエリはありますか? サブクエリは通常、私の経験ではかなり遅いです。
また、StackExchange コードがどのようにそれを行うかについても知りたいです。
ご不明な点がございましたら、お気軽にお問い合わせください。
乾杯。