2017-11-06 6 views
0

Googleには一連のデバイスがあり、すべてにセンサーが搭載されています。すべてのデバイスにはいくつかの共通のセンサーセットがありますが、一部のデバイスにはセンサーが追加されています。すべてのセンサは異なる離散化レベルを持ち、一部のセンサは時には非常に高速に変化することがあり、時には変更できないことがあります。しばらくClickhouseにセンサーデータを保存する最良の方法は何ですか?

Timestamp, Temp, Latitude, Longitude, Speed..., AdditionalSensor 
111, 24, 54.111, 23.121, 10 ... 1 
112, 23, 55.111, 23.121, 13 ... 2 
113, 23, 55.111, 23.122, 15 ... 1 

を新しいセンサーができます たとえば、私たちはDeviceAを持っていると、フォーム(NULL値が変更されないことを意味します)でパケットのストリームを持っている:

Timestamp, Temp, Latitude, Longitude, Speed... 
111, 20, 54.111, 23.111, 10 
112, 20, NULL, NULL, 13 
113, 20, NULL, 23.112, 15 

とDeviceBいくつかのデバイスに追加することができます。 すべてのセンサーは数値タイプ(Int32、UInt8、Float32)のいずれでもかまいません

このデータは、dau、mau、retention、GPS座標クラスタリングなどの計算に使用されます。

私たちは、単にいくつかのテーブルを作成することができます。ここ

CREATE TABLE Sensors 
(
     Date Date, 
     Id FixedString(16), 
     DeviceNumber FixedString(16), 
     TimeUtc DateTime, 
     DeviceTime DateTime, 
     Version Int32, 
     Mileage Int32, 
     Longitude Float64, 
     Latitude Float64, 
     AccelX Float64, 
     AccelY Float64, 
     AccelZ Float64 
     ... 
) ENGINE = MergeTree(Date, (DeviceNumber, TimeUtc), 8192); 

しかし、二つの問題:センサーの異なるセットのサポートはありませんが、時には我々は、変更なしの場合のいくつかのセンサ値にnull値を持っており、それは次のようになりタイムスタンプの前に最後の非ヌル値を表示することは素晴らしいことです。

最初の問題は、SensorName、Timestamp、Date、Valueの各フィールドを持つテーブルを作成することで解決できます。しかし、どのように正しいタイプを選択するのですか?異なるタイプのテーブルを使用する必要がありますか? おそらく私たちはグラファイトエンジンを使用する必要がありますが、残念なことに、私はその経験がありません。だから、どんな助けも本当にありがたいです。どのセンサの値も変更しないでください。

更新

私はNULL値をどのように扱うかの方法を発見しました。

SELECT anyLast(Lights) FROM test where TimeUtc <= toDateTime('2017-11-07 11:13:59'); 

残念ながら、私たちは、オーバーラップウィンドウ関数のいくつかの種類(clickhouseで彼らのサポートはありません)を使用して、不足しているすべての値を埋めることはできません。列の値を受けた私たちは、最後の要求する「anyLast」機能を使用することができます。したがって、NULL可能フィールドの場合は、NULL値のみを使用し、ゼロ以外のフィールドの場合は、ゼロ値を含むすべての値が使用され、両方の方法が正しくありません。回避策は、行内のすべてのNULL値に対してanyLast値を指定してselectを使用して挿入する前に、NULL値を入力する方法です。

答えて

1

Clickhouseは時系列データベースのように使用できます。

テーブル定義によって、動的な指標がないことが制限されています。だからあなたがNULL値を扱おうとしているのです。

あなたは、センサ値については、この表を使用することができます。

CREATE TABLE ts1(
    entity String, 
    ts UInt64, -- timestamp, milliseconds from January 1 1970 
    s Array(String), -- names of the sensors 
    v Array(Float32), -- sensor values 
    d Date MATERIALIZED toDate(round(ts/1000)), -- auto generate date from ts column 
    dt DateTime MATERIALIZED toDateTime(round(ts/1000)) -- auto generate date time from ts column 
) ENGINE = MergeTree(d, entity, 8192) 

ここでは、デバイスAのセンサ値をロードしている:

INSERT INTO ts1(entity, ts, s, v) 
VALUES ('deviceA', 1509232010254, ['temp','lat','long','speed'], [24, 54.111, 23.121, 11]) 

照会deviceAの一時データ:

SELECT 
    entity, 
    dt, 
    ts, 
    v[indexOf(s, 'temp')] AS temp 
FROM ts1 
WHERE entity = 'deviceA' 

┌─entity─┬──────────────────dt─┬────────────ts─┬─temp─┐ 
│ deviceA│ 2017-10-28 23:06:50 │ 1509232010254 │ 24 │ 
└────────┴─────────────────────┴───────────────┴──────┘ 

チェック詳細な使用方法についてはthis full answerを参照してください。

関連する問題