2

記事の投票システムがあります。記事は「ストーリー」テーブルに保存され、すべての投票は「投票」テーブルに保存されます。'stories' テーブルの id は 'votes' テーブルの item_name と同じです (したがって、各投票は item_name の記事に関連しています)。

投票の合計が10になると、「ストーリー」テーブルの「表示」フィールドが「1」の値に更新されるようにしたいと思います。

表示 = 0 のすべての投稿をチェックするために 1 時間ごとに実行される cron ジョブを設定することを考えていました。 . 多くのサーバー リソースを占有する可能性があるため、効率的かどうかはわかりません。

それで、誰かがタスクを実行できるcronジョブを提案できますか?

これが私のデータベース構造です:

ストーリー テーブル

ここに画像の説明を入力


投票表

ここに画像の説明を入力


編集:

たとえば、「ストーリー」テーブルの次の行:

id| 12
st_auth | 著者名
st_date | ストーリーの日付
st_title| ストーリータイトル
st_category| ストーリー カテゴリ
st_body| ストーリー本文
表示| 未証明の場合は 0、承認済みの場合は 1

この行は、「投票」テーブルのこの行に関連しています

id| 83 アイテム名| 12 (記事の ID ) 賛成票の場合は 1 - 反対票の場合は 1 ...

4

3 に答える 3

2

いくつかのこと:

  1. item_name実際には article テーブルの ID であるのに、なぜvotes テーブルの列に名前を付けたのですか? これは、int(11) 対 var_char(255) であるという点で、article テーブルで一致させることをお勧めします。また、votes テーブルに外部キー制約を追加して、記事が削除された場合でも、votes テーブルの行を孤立させないようにする必要があります。

  2. vote_value列が int(11) なのはなぜですか? 2 つの状態 (1 または -1) しかできない場合は、tinyint(1) signed (-1 の場合) を実行できます。

  3. 投票表のip列は少し気になります。IP による「一意の」投票を規制している場合、プロキシ IP を考慮しましたか? このようなことはアカウント レベルで処理する必要があるため、同じプロキシ IP の複数のユーザーが個別の投票を発行できます。

  4. 列に 0 と 1 のどちらのフラグを付けるかを決定するために cron ジョブを実行することはしませんshowing。むしろ、記事に反対票が投じられるたびにカウントを発行します。したがって、誰かが賛成票または反対票を投じた場合、ストーリーの新しい価値を計算し、将来の読み取りのためにキャッシュに保存します。

于 2011-12-21T22:52:39.710 に答える
1

トリガー(トリガーを挿入)を使用して、そこで(データベース自体で)ロジックを処理しますか?これにより、ポーリング コードが完全に削除されます (cron ジョブ)。また、外部キー(VOTES)を主キー(STORIES)と同じ(少なくともタイプ)に保ちますか?

ポーリングの代わりにトリガーを使用すると、長期的にはよりクリーンになります。

データベースを指定しませんが、TSQL (SQL Server 用) ではこれに近い可能性があります

CREATE TRIGGER myTrigger 
ON VOTES
FOR INSERT
AS

DECLARE @I INT --HOLDS COUNT OF VOTES

DECLARE @IN VARCHAR(255) --HOLDS FK ID FOR LOOKUP INTO STORIES IF UPDATE REQUIRED

SELECT @IN = ITEM_NAME FROM INSERTED

SELECT @I = COUNT(*) FROM VOTES WHERE ITEM_NAME = @IN

IF (@I >= 10)

BEGIN

  UPDATE STORIES SET SHOWING = 1 WHERE ID = @IN --This is why your PK/FK should be refactored

END
于 2011-12-21T22:43:09.133 に答える
1

このクエリを使用すると、すべての記事のリストと、関連する投票数を含む列が取得されます。

SELECT s.*, SUM(v.vote_value) AS votes_total
FROM stories AS s INNER JOIN votes AS v
ON v.item_name = s.id
GROUP BY v.vote

votes_total > 10このようにして、cron ジョブを必要とせずに、 でフィルタリングできるビューを作成できます。

または、次のような通常のクエリとして使用できます。

SELECT * FROM (
  SELECT s.*, SUM(v.vote_value) AS votes_total
  FROM stories AS s INNER JOIN votes AS v
  ON v.item_name = s.id
  GROUP BY v.vote
) WHERE votes_total > 10;
于 2011-12-21T22:46:48.120 に答える