1

trafficユーザーが特定のを追跡しているシナリオを考えてみましょうcities。トラフィックは 2 時間ごとに更新され、グラフをプロットするために以前のデータを保持する必要があります。だから私はtraffic_statsこのようなテーブルを持っています -

traffic_stats(id,city_id,user_id,traffic,created_at)

(指定されたトラフィックは数値です)

一意 city_idの s を取得し、これらの都市の現在のトラフィック統計を取得し、このテーブル自体に新しいエントリを追加する統計リフレッシャー デーモンがあります。デーモンはこのクエリを使用してフェッチしますcity_id-

SELECT * FROM traffic_stats GROUP BY city_id

city_id同じテーブルにそれぞれの新しいエントリを追加します。user_idどのユーザーがその都市を購読しているかは問題ではないため、新しいエントリごとの属性は 0 です。が表にある場合city_idは、traffic_stats が更新されます。

フロントエンドでは、ユーザーのデータを取得するために次のクエリが実行されます -

SELECT * FROM 
(SELECT * FROM traffic_stats WHERE user_id = #{session[:user_id]} ORDER BY created_at DESC)
as traffic_for_user_in_descending_order 
GROUP BY city_id

これにより、city_id の単一の最新エントリが得られます。

100 人のユーザーが 200 のユニークな都市を追跡している場合、traffic statsテーブルには 2 時間ごとに 200 の新しいエントリが存在するという事実を除けば、これは問題なく動作するはずです。これは 1 日 2400 エントリで、テーブルは増え続けます。

ここで、ユーザーが追跡している都市に関するデータを含む 1 つのテーブルと、リフレッシャー デーモンがエントリを追加する別のテーブルを持つことができます。しかし、このアプローチにパフォーマンス上の利点があるかどうかはわかりません。

4

2 に答える 2

2

city_iduser_idを別のテーブルに分割する必要がありますuser_city。次に、のようなクエリSELECT DISTINCT city_id from user_cityを実行すると、デーモンの追跡された都市のリストが表示されます。インデックスやFKなどが正しく設定されていれば、テーブルのサイズは大きくなりません。

user_idが常に0の場合、クエリtraffic_statsはどのように機能しますか?WHERE user_id = #{session[:user_id]}

可能なすべてのインデックスを使用する複雑なクエリで問題ありません。統計の要約を毎日/毎週行う場合は、rallsi23が提案するように、集計データを格納するためのテーブルも作成する必要があります。そのため、統計テーブルのすべての行を読み取って、ユーザーへの出力/レポートを生成しているわけではありません。

于 2012-10-05T06:54:00.583 に答える
2

最初の select ステートメントでテーブル全体をスキャンするのではなく、個別のCityテーブルを作成して、そこから個別の都市 ID をクエリできるようにすることをお勧めします。また、データベースの読み取りが少し簡単になります。これを行いたくない場合は、 を使用することをお勧めしSELECT DISTINCT city_id FROM traffic_statsます。これにより、取得する情報が少なくなります。

この場合、情報を使用しているアプリケーションが単純であるため、テーブルを 1 つにするのが妥当と思われます。履歴データについては、集計情報を格納する別のテーブルを作成すると便利な場合があります。特定の期間 (日、週、月など) の平均を選択して保存し、プライマリ テーブルを整理してから、ユーザー ID に基づく情報に基づいてさらにフィルタリングすることができます。これにより、データベースのディスク使用量とクエリ時間が削減されます。

個人的には、物事を可能な限り分解するのが好きです。より複雑なクエリになりますが、データベースからの情報の使用と読み取りがはるかに簡単になると思います。

于 2012-10-05T02:22:05.753 に答える