2

写真サイトのホームページに掲載する写真が並んでいます。写真家は、一度に数十枚のショットをアップロードする傾向があります。つまり、編集者はアップロードの中から最高のものを選択し、同じ写真家の複数のショットを次々とキューに入れる可能性が非常に高くなります。しかし、1 人のフォトグラファーが何時間もホームページを所有することは望んでいません。

現時点では、キューを手動でソートして、可能な限りキューに入れられた時間順 (FIFO) になるようにしていますが、同じ写真家による 2 つのショットが 5 スロットよりも近くにならないようにしています。これを自動化したいと考えています。

PHP で並べ替えを実行できることはわかっていますが、単一の MySQL クエリで正しい順序でキューを取得できますか?

テーブル構造はこんな感じ。2 つの隣接するショットの queued_time を入れ替えてキューを並べ替えます - 理想的ではありませんが、機能します。

homepage_queue
--------------
id INT NOT NULL
photo INT NOT NULL
queued_time INT NOT NULL

photos
------
id INT NOT NULL
photographer INT NOT NULL

関連する SO の質問を参照すると、このページが表示されました。これは、Oracle の LAG 関数をエミュレートする必要があることを示唆しているようです。ランキング関数と mysql.html?page=2

特に、最後の 5 行を確認する必要があると考えると、あまりにも乱雑に見えて、悲鳴をあげて逃げ出し、PHP で実行したくなるのですが、もっと簡単な方法はありますか?

私たちは通常、1 週間、1 枚の写真につき 1 時間、キューを詰め込みます。

キューの最後には、「5 つずつ」ルールを満たす方法で並べ替えることができない写真が必ずあります。ジョブは 24 時間ごとに実行される可能性が高く、アップロードの安定したストリームでは、キューの末尾が混乱しても問題ないため、それは問題ではありません。

4

2 に答える 2

1

ミックスに別のテーブルを追加します。これは、あなたのWebサイトに登場した最後の5人の写真家を記録したものです。

次の写真を選択するためのクエリ:

SELECT
  homepage_queue.photo
FROM
  homepage_queue
INNER JOIN
  photos
    ON photos.id = homepage_queue.photo
LEFT JOIN
  (SELECT photographer, COUNT(*) AS occurances FROM last_five GROUP BY photographer) AS last_five
    ON last_five.photographer = photos.photographer
ORDER BY
  last_five.occurances ASC,
  homepage_queue.queued_time
LIMIT
  1

写真を選んだら:
-その値をどこかに保存します
-最も古いエントリを削除します-新しい写真の写真家に関連するlast_five
新しいエントリを追加し ます-選択した写真をキューから削除します last_five

少し余分なメンテナンスがありますが、比較的シンプルでそれ自体を維持するソリューションです。

  • キューが2人の写真家でいっぱいの場合、彼らは交代します
  • 新しい写真家が数枚の写真をアップロードすると、それらが優先されます
  • 過去5回の発生が最も少ない写真家が常に優先されます

編集:

これは、にのみ焦点を当てることによって問題を単純化しますwhat's next?

このプロセスをループで24回繰り返すことにより、まったく新しいキューを生成するようにこれを適応させることができます。next photoあなたが新しいキューにプッシュする各イテレーション。

24枚の写真のリストを1回生成してから、1時間ごとに1回の繰り返しを使用することもできます。
-1枚の写真を削除する
-この方法を使用して1枚の写真を追加する

次に、24枚の写真の一定のリスト、リストの最後に常に「正しい写真」を追加する方法、および24枚のリストをいつでも並べ替えることができます。

于 2012-10-17T19:32:35.440 に答える
1

実際、質問をするときは、データ構造に関する情報を提供する必要があります。基になるテーブルに次の列があるとします。

  • キューの位置
  • 写真家
  • 写真付き身分証明書

その場合、次は、キューの最初の写真に基づいて、写真家ごとに 1 行を返します。

select q.*
from Queue q join
     (select PhotographerId, min(QueuePosition) as minQP
      from queue q
      group by PhotographerId
     ) qp
     on q.QueuePosition = minQP
order by q.QueuePosition

以下は、実際のデータのバリエーションです。

select q.*
from Queue q join
     (select Photographer, min(QueuedTime) as minQT
      from HomePage_Queue hpq join
           Photos p
           on hpq.PhotoId = p.Id
      group by Photographer
     ) qp
     on q.QueuedTime= minQT
order by q.QueuedTime

これは、QueuedTimes が一意であると仮定して機能します。そうでない場合は、もう少し作業を行う必要があります。

于 2012-10-17T19:10:27.183 に答える