InfluxDB 1.7 の使い方 その1( INSERT , SELECT , GROUP BY)
InfluxDB は時系列データベースで、時間情報(タイムスタンプ) を持った一連の値を扱うことに特化したデータベースで、次のような特徴があります。
- 時系列データ専用に作成されたデータストア
- SQLに似たクエリ言語
- データに期限を持たせ、自動的に削減できる
- 収集したデータから低精度のデータを生成できる
【動作環境】
- CentOS 7
- InfluxDB 1.7
InfluxDB の操作
InfluxDB を操作するには、 influx コマンドを使用したインタラクティブシェルや HTTP リクエストを使用した方法が用意されています。
コマンドラインの場合
例えば、influx コマンドを使用したデータベースの照会は次のようになります。
$ influx
Connected to http://localhost:8086 version 1.7.7
InfluxDB shell version: 1.7.7
> SHOW DATABASES
name: databases
name
----
_internal
sec_env
>
HTTP リクエストの場合
HTTP リクエストを使用したデータベースの照会は次のようになります。
$ curl -G http://localhost:8086/query --data-urlencode "q=SHOW DATABASES"
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"],["sec_env"]]}]}]}
データベースの作成
データベースを作成します。デフォルトでは、 /var/lib/influxdb/ に data ディレクトリや meta ディレクトリ, wal ディレクトリが作成され、その配下に保存されていきます。
コマンドラインの場合
$ influx
Connected to http://localhost:8086 version 1.7.7
InfluxDB shell version: 1.7.7
> CREATE DATABASE データベース名
HTTP リクエストの場合
$ curl -G http://localhost:8086/query --data-urlencode "q=CREATE DATABASE データベース名"
{"results":[{}]}$
データの登録
データの登録を行います。
コマンドラインの場合
※ influx を実行し、インタラクティブシェルで実行しています。
「CREATE DATABASE」で作成したデータベースを使用するため、 USE コマンドで使用するデータベースを切り替えます。データを登録するには、次のような INSERT 文を実行します。
> USE データベース名
> INSERT temperature,zone=BLD10 value=28.8
データを書き込む構文は、次のようになります。
INSERT <measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]
measurement は、データを保存する入れ物の名称(テーブルのようなもの)で、順にタグのセット,値のセット(フィールドセット),タイムスタンプを指定することができます。
上記例では、 temperature という入れ物(measurement) に zone というタグキーと BLD10 というタグ値, value というフィールドキーと 28.8 というフィールド値を登録することになります。タグキーとタグ値の組み合わせは複数指定することができタグセットといいます。また、フィールドキーとフィールド値も複数指定することができフィールドセットと言います。
> USE データベース名
> INSERT temperature,zone=BLD10,machine=A-512 temp=28.8,voltage=14.7
HTTP リクエストの場合
HTTP リクエストでデータを登録するには、 POST メソッドで write API (エンドポイント)を実行します。データを登録する場合は、データをそのまま送る --data-binary をオプション指定します。
$ curl -i -X POST 'http://localhost:8086/write?db=sec_env' --data-binary 'temperature,zone=BLD13 value=27.7'
db=データベース名の部分でデータ登録を行うデータベースを指定し、 --data-binary に measurement とタグセット,フィールドセットを指定します。
データの取得
コマンドラインの場合
登録したデータを取得するには、 SELECT 文を使用します。まず、使用するデータベースを切り替えます。その後、 measurement を指定して SELECT 文を実行します。
> USE sec_env
Using database sec_env
> SELECT * FROM temperature
name: temperature
time value zone
---- ----- ----
1564669980530312310 28.8 BLD10
1564673360512276186 27.6 BLD13
1564674237929836764 28.3 BLD13
>
このままの表示では、時間がわかりにくいので influx のオプションにタイムスタンプの形式及び精度を指定します。(デフォルトの精度はナノ秒)
$ influx -precision rfc3339
Connected to http://localhost:8086 version 1.7.7
InfluxDB shell version: 1.7.7
> USE sec_env
Using database sec_env
> SELECT * FROM temperature
name: temperature
time value zone
---- ----- ----
2019-08-01T14:33:00.53031231Z 28.8 BILD10
2019-08-01T15:29:20.512276186Z 27.6 BLD13
2019-08-01T15:43:57.929836764Z 28.3 BLD13
HTTP リクエストの場合
HTTP リクエストでデータを取得するには、 GET メソッドで query API (エンドポイント)を実行します。
$ curl -G 'http://localhost:8086/query' --data-urlencode "db=sec_env" --data-urlencode "q=SELECT * FROM \"temperature\""
{"results":[{"statement_id":0,"series":[{"name":"temperature","columns":["time","value","zone"],"values":[["2019-08-01T14:33:00.53031231Z",28.8,"BILD10"],["2019-08-01T15:29:20.512276186Z",27.6,"BLD13"],["2019-08-01T15:43:57.929836764Z",28.3,"BLD13"]]}]}]}
URL パラメータに 「 db 」 (データベース名)と 「 q 」 (クエリー)を指定すると、結果を JSON で返してくれます。
$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sec_env" --data-urlencode "q=SELECT * FROM \"temperature\""
{
"results": [
{
"statement_id": 0,
"series": [
{
"name": "temperature",
"columns": [
"time",
"value",
"zone"
],
"values": [
[
"2019-08-01T14:33:00.53031231Z",
28.8,
"BILD10"
],
[
"2019-08-01T15:29:20.512276186Z",
27.6,
"BLD13"
],
[
"2019-08-01T15:43:57.929836764Z",
28.3,
"BLD13"
]
]
}
]
}
]
}
JSON を成形した状態で取得したい場合は、 「 pretty=true 」 と指定します。
データの取得(WHERE句)
タグを指定してデータを抽出するには、 WHERE 句に タグキーとタグ値を指定します。
> SELECT time,value FROM temperature WHERE zone='BLD13';
name: temperature
time value
---- -----
2019-08-01T15:29:20.512276186Z 27.6
2019-08-01T15:43:57.929836764Z 28.3
フィールドを指定してデータを抽出するには、 WHERE 句に フィールドキーとフィールド値を指定します。
> SELECT time,value FROM temperature WHERE value >= 28;
name: temperature
time value
---- -----
2019-08-01T14:33:00.53031231Z 28.8
2019-08-01T15:43:57.929836764Z 28.3
時間を指定したい場合は、 WHERE 句に time を指定します。
> SELECT * FROM temperature WHERE time >= '2019-08-01T14:33:00Z' AND time < '2019-08-01T15:30:00Z';
name: temperature
time value zone
---- ----- ----
2019-08-01T14:33:00.53031231Z 28.8 BILD10
2019-08-01T15:29:20.512276186Z 27.6 BLD13
HTTP リクエストの場合
HTTP リクエストで WHERE 句を指定してデータを取得するには、 「 q 」 パラメーターのクエリに WHERE 句を含めます。
$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sec_env" --data-urlencode "q=SELECT \"value\" FROM \"temperature\" WHERE \"zone\"='BLD13'"
{
"results": [
{
"statement_id": 0,
"series": [
{
"name": "temperature",
"columns": [
"time",
"value"
],
"values": [
[
"2019-08-01T15:29:20.512276186Z",
27.6
],
[
"2019-08-01T15:43:57.929836764Z",
28.3
]
]
}
]
}
]
}
集計いろいろ( GROUP BY )
GROUP BY は、 RDBMS などにみられるグループ化するための指定方法以外に時系列データベースならではの指定方法が存在します。
よくある GROUP BY
RDBMS などの GROUP BY と同じように タグキーを指定して集計を行うことができます。平均を求める mean 関数を使用してタグキー( zone )単位に結果を抽出します。
> SELECT mean(value) FROM temperature GROUP BY zone;
name: temperature
tags: zone=BILD10
time mean
---- ----
1970-01-01T00:00:00Z 28.8
name: temperature
tags: zone=BLD13
time mean
---- ----
1970-01-01T00:00:00Z 27.950000000000003
>
拡張された GROUP BY
InfluxDB では、 GROUP BY time() という拡張構文を使用する事ができます。時間間隔,開始オフセット,時間間隔内にデータが存在しなかった場合に何をセットするか(ヌル、数値指定、線形補完、ポイント無し、前データ値)などを指定することができます。
例えば、3分間隔で平均をとりたい場合、次のようなクエリーを発行します。
> SELECT mean(value) FROM temperature WHERE time >= '2019-08-01T15:29:00Z' AND time < '2019-08-01T15:45:00Z' GROUP BY time(3m);
name: temperature
time mean
---- ----
2019-08-01T15:27:00Z 27.6
2019-08-01T15:30:00Z
2019-08-01T15:33:00Z
2019-08-01T15:36:00Z
2019-08-01T15:39:00Z
2019-08-01T15:42:00Z 28.3
時間間隔内にデータが存在しなかった場合に、「0」をセットするには次のように fill(0) を付加したクエリーを発行します。
> SELECT mean(value) FROM temperature WHERE time >= '2019-08-01T15:29:00Z' AND time < '2019-08-01T15:45:00Z' GROUP BY time(3m) fill(0);
name: temperature
time mean
---- ----
2019-08-01T15:27:00Z 27.6
2019-08-01T15:30:00Z 0
2019-08-01T15:33:00Z 0
2019-08-01T15:36:00Z 0
2019-08-01T15:39:00Z 0
2019-08-01T15:42:00Z 28.3
>
InfluxDB の GROUP BY を使った構文は、次のようになります。
SELECT <function>(<field_key>) FROM_clause
WHERE <time_range>
GROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option>)]
関数いろいろ
集計関数
- COUNT()
- DISTINCT()
- INTEGRAL()
- MEAN()
- MEDIAN()
- MODE()
- SPREAD()
- STDDEV()
- SUM()
選択関数
- BOTTOM()
- FIRST()
- LAST()
- MAX()
- MIN()
- PERCENTILE()
- SAMPLE()
- TOP()
変換関数
- CEILING()
- CUMULATIVE_SUM()
- DERIVATIVE()
- DIFFERENCE()
- ELAPSED()
- FLOOR()
- HISTOGRAM()
- MOVING_AVERAGE()
- NON_NEGATIVE_DERIVATIVE()
- NON_NEGATIVE_DIFFERENCE()
予測関数
- HOLT_WINTERS()