データベースに可変数のフィールドを持つ測定値を保存する最も効率的な方法は何ですか?

StackOverflow https://stackoverflow.com/questions/1629458

  •  06-07-2019
  •  | 
  •  

質問

環境センサーから測定値を収集するデータ収集システムがあり、河川または水路を流れる水の速度を測定します。各測定では、固定数の値(日付、時刻、温度、圧力など)と速度値のリストが生成されます。
もともとセンサーは3つの速度値を提供していたので、FireBirdデータベースの単一テーブルの独自の列に各値を保存しました。その後、最大9つの速度値を出力できるセンサーが導入されたため、さらに6列追加しました。ほとんどのセンサーは9個未満の値を使用しますが、ほとんどの列にゼロが含まれていれば問題ないと考えています。
しかし今、私は1から256の値を出力できる新しい世代に直面しています。特にほとんどの測定にはまだ3から9の値しか含まれていないため、別の247列を追加するのはあまり効率的ではないと思います。
測定値は10分ごとに収集され、データベースには30から50個のセンサーのすべてのデータが含まれているため、データの合計量は数年後に非常に重要になりますが、ランダムな期間の概要/グラフを生成できる必要があります。

では、値の変数リストを保存する最も効率的な方法は何でしょうか?
各レコードには固有のIDがあるため、すべての速度値を別々のテーブルに保存でき、各値にはレコードIDのタグが付けられていると思います。これはあまり効率的ではなく、しばらくすると非常に遅くなると感じています。

役に立ちましたか?

解決

効率的なインデックスを使用すると、データベースはテーブル内の大量のデータを処理できます。したがって、次のテーブル構造を使用できます。

create table measurements (
     id,
     seq integer, -- between 1 and 256
     ts timestamp, -- Timestamp of the measurement
     value decimal(...)
)

id id、seq および ts にインデックスを作成します。これにより、データを効率的に検索できます。データベースに不信がある場合は、数百万行を挿入し、数回の選択を実行して、どれだけうまくいくかを確認してください。

比較のために、ここには1億1,200万行のOracleデータベースがあり、タイムスタンプまたはIDで120ms(0.12s)以内にレコードを選択できます

他のヒント

テキストフィールドにシリアル化されたデータを保存できます。たとえば、測定値を次のようにJSONエンコードします。

[<velocity-value-1>, <velocity-value-2>, ...]

次に、コード内で、クエリ後に値を逆シリアル化します。

これは、保存された値ではなく、他のフィールドのみでクエリをフィルタリングする場合に有効です。値でフィルタリングすると、 WHERE 句で値を使用すると悪夢になります。

2番目のテーブルに行きます:

table measurements (Id, DateTime, Temperature, Pressure)
table velocity (Id, MeasurementId, Sequence, Value)

Velocity.MeasurementId Measurements.Id を参照します。
Velocity.Sequence は、その測定値の速度値のインデックスです(1〜256)。

これらのテーブルにできるだけ現実に近いデータを入力し、sqlステートメントをテストして最適なインデックスを見つけます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top