1

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

クエリはデータベースから取得され、接頭辞が付けられSELECTAND [$badge_id] NOT IN (...)サブクエリ条件が追加されます。[$badge_id]その後、現在のバッジ IDに置き換えられます。クエリが実行され、バッジを付与する必要があるユーザー ID のリストが返されます。

ハッシュ フィールドは、PHP スクリプトで定義されたキーを使用して、クエリの HMAC-SHA1 ハッシュを格納するために使用されます。この背後にある考え方は、SQL インジェクション攻撃が発生した場合でも、攻撃者はスクリプト内のキーにアクセスできず、より危険なクエリを偽造できないというものです。

2 つの質問があります。

  1. テーブル内の SQL は本当に悪い方法ですか? もしそうなら、なぜですか?私は代替案を受け入れます。
  2. 同じクエリを達成するためのより効率的なクエリはありますか? サブクエリは通常、私の経験ではかなり遅いです。

また、StackExchange コードがどのようにそれを行うかについても知りたいです。

ご不明な点がございましたら、お気軽にお問い合わせください。

乾杯。

4

1 に答える 1

0

これは悪い考えのように聞こえます。スキーマを変更した場合はどうなりますか? 次に、テーブル内のすべての行を無効にする必要があります。トリガーを使用して、バッジを「トリガー」したアクションを記録します。次に、cron スクリプトがバッジを授与します。

あなたの場合、誰かにコメント バッジを授与する必要があるかどうかを判断するのは非常に単純なクエリなので、CRON から直接処理します。

SELECT * FROM comments
LEFT JOIN users_badges ON users_badges.user_id = comments.user_id AND users_badges.description = 'First Comment'
WHERE users_badges.badge_id IS NULL
GROUP BY comments.user_id

理論的には、返された結果ごとにバッジ レコードを挿入できます。これは私の頭の中から外れていましたが、あなたはその考えを理解しています。

より複雑なクエリの場合は、単純化するために何らかのアクティビティ テーブルに挿入することになります。これは、実装を少し分離するのにも役立ちます。バッジの「説明」が将来変更された場合はどうしますか? 正規化はそのようなことを助けます。

于 2011-12-13T09:27:12.060 に答える