2017-11-06 6 views
0

topicというテーブルがあり、そのテーブルのカラムはlike_countです。MySQLデザイン:特定の期間内に大部分のアクションを含むコレクションを取得するクエリ

このテーブルにクエリを書き込んで、過去7日間に最も好きだった10のトピックを意味する「過去7日間で最も人気のあったトピックのトップ10を」と尋ねることは可能ですか?追加の監査テーブルを作成せずに

topic_like_auditのような監査テーブルを作成することで、これは2つの列(topic_idcreated_at)を作成することによってこれを行うと考えていました。そのIDを持つトピックが好きになるたびに、新しいレコードが監査テーブルに格納されます。次に、created_at列を使用して過去7日間のすべての結果を集計し、その期間内に最も多くのレコードを持つものでランク付けするクエリを作成できます。

しかし、私はそれがスケーラブルな解決策であるとは想像できません...短期間ではうまくいくかもしれませんが、何百万人、あるいは何十万人もの好きなトピックを持っているときは必ず悪くなるはずです。

このようなことを行う上での優れた標準的な解決策、または私のアプローチは十分ですか? P.S.私はDBのnoobです。

+0

推奨される監査テーブルは適切なインデックス付けが可能でなければなりません。 (おそらく月または年によって)、および/または現在のサイト操作に関連しない行をアーカイブすることを検討してください。 –

+0

@Used_By_Alreadyあなたは実際に本当に良い点を作っています。テーブルサイズを減らすために特定の時間枠よりも古いレコードを削除することができます。先端に感謝します。 – Lansana

+0

解決方法は、過去7日間で最も好きなトピックのトップ10を与えてください。 "あなたはそれぞれのような日時情報が必要です。 –

答えて

1

挿入が少し遅くなるかどうかによって異なります。

あなたができることは、最初にいくつかのクエリによって上位10のトピックのデータを生成できることです。 このリストは、mysqlまたは任意のキャッシングレイヤーで管理することができます。キャッシングレベルを維持すると、検索が高速になるため、このリストは良好です。

新しいトピックのように挿入するたびに、現在のトピックがトピックのようにリスト内の最小限のものと比較することができます。現在が大きい場合はスワップできます。このために、優先度キューをデータ構造として使用すると、O(logn)時間につながります。

このプロセスは、一貫性のあるシステムではなく最終的に一貫性のあるシステムとなる可能性があるため、さらに遅れる可能性があります。これを待ち行列にプッシュして、作業者がさらに処理できるようにすることができます。

1

「好き」がいつ発生したのかわからないようですね?それぞれの「好き」(または「好きな」バッチ)を日時(または日)に結び付けることで、それを行うことはできません。

「好き」が発生した場合は、topicdatetimeのテーブル(TodaysLikes)に保存します。各日の終わりに、昨日のデータをtopic,date(日時ではない)、countのサマリーテーブル(LikesSummary)に要約します。その後、TodaysLikesから削除してください。

次に、このトップ10を取得します。

SELECT topic, SUM(count) AS likes 
    FROM LikesSummary 
    WHERE date >= CURDATE() - INTERVAL 7 DAY 
    ORDER BY likes DESC 
    LIMIT 10 

さらなる最適化が直接発生する「のような」が、夜間の要約の一部としてそれを行うようにlike_countをバンプすることはありません。これは、like_countが最新のものではなく、昨夜までしかカウントされないことを意味します。

+0

答えをありがとう。すでにこれを解決していたのですが、複数のテーブルに関する優れたアドバイス。私はストレージのサイズを小さくしたい場合は、良いアイデアかもしれません。しかし、当面はすべての記録を歴史的な目的のために保管したいと考えています。 – Lansana

関連する問題