このトピックでは、Lindorm GanosBase SQL を使用して、車載インターネット (IoV) シナリオから収集された軌跡ポイントを Lindorm ワイドテーブルに書き込み、時空間範囲に基づいて軌跡ポイントをクエリする方法について説明します。
前提条件
Java Development Kit (JDK) 1.8 以降がインストールされていること。
SQL を使用して LindormTable に接続して使用するときに必要なエンドポイントを取得していること。Lindorm インスタンスのホワイトリストが構成され、クライアントの IP アドレスがホワイトリストに追加されていること。詳細については、LindormTable への接続をご参照ください。
手順
軌跡ポイントを Lindorm ワイドテーブルに書き込み、軌跡ポイントをクエリするには、次の手順を実行する必要があります。
時空間テーブルを作成し、収集した軌跡ポイントをテーブルに書き込む
Lindorm-cli を使用して LindormTable に接続し、データを書き込む
LindormTable に接続します。このトピックでは、Lindorm-cli を使用して、Linux にデプロイされたクライアントを LindormTable に接続します。
JDBC を使用して LindormTable に接続するには、Java JDBC API を使用したアプリケーションの開発をご参照ください。
Lindorm-cli のインストールパッケージをダウンロードします。
Lindorm-cli のインストールパッケージを解凍します。
接続情報を取得します。次に、次の形式のコマンドを実行して LindormTable に接続します。
./lindorm-cli -url <jdbc url> -username <Username> -password <Password>
パラメーター
例
パラメーター値の取得方法
jdbc url
jdbc:lindorm:table:url=http://ld-bp17j28j2y7pm****-proxy-lindorm-pub.lindorm.rds.aliyuncs.com:30060
SQL を使用して LindormTable に接続して使用するときに必要なエンドポイント。エンドポイントの取得方法の詳細については、LindormTable への接続をご参照ください。
ユーザー名
root
LindormTable のクラスタ管理システムでユーザー名を表示したり、パスワードをリセットしたりできます。詳細については、ユーザーのパスワードを変更するをご参照ください。
パスワード
root
次の結果が返されます。
Connected to jdbc:lindorm:table:url=http://ld-bp17j28j2y7pm****-proxy-lindorm-pub.lindorm.rds.aliyuncs.com:30060 lindorm-cli version: 1.0.15
次のいずれかの方法を使用して、時空間テーブルを作成します。
時空間テーブルは、軌跡ポイントを格納するために使用されます。軌跡ポイントには、経度 (x)、緯度 (y)、および時間 (t) 情報が含まれています。経度と緯度の情報は、2 つの方法で格納されます。次の表に、Lindorm GanosBase で経度と緯度の情報を格納するために使用される方法を示します。
格納方法
説明
ポイントに関する経度と緯度の情報を、1 つの列に
geometry point
として格納します。この方法で格納されたデータは、より優れた読み取りおよび書き込みパフォーマンスを提供できます。
ポイントの経度と緯度の情報を 2 つの列に個別に格納します。
履歴の経度と緯度の情報は、2 つの列に個別に格納されます。この方法で格納されたデータの読み取りおよび書き込みパフォーマンスは、ジオメトリポイントとして格納されたデータほど高くありません。
ポイントに関する経度と緯度の情報を 1 つの列に
geometry point
として格納します。次のステートメントを実行して、この方法で経度と緯度の情報を格納する時空間テーブルを作成できます。CREATE TABLE gps_data (id int, g geometry(point), t timestamp, ship_name varchar, PRIMARY KEY(id, t));
パラメーター
説明
g
空間データを格納する列。この列に格納されるデータの型は
Geometry(Point)
です。t
時間データを格納する列。この列は、Time、Timestamp、および Long データ型をサポートしています。この列の Long 型の値は、ミリ秒単位の精度の UNIX タイムスタンプを示します。
ship_name
名前を格納する列。たとえば、このテーブルの軌跡ポイントが生成された船の名前を格納できます。
PRIMARY KEY(id, t)
テーブルのプライマリキー。
id
列とt
列が含まれます。ポイントに関する経度、緯度、および時間情報を 2 つの列に個別に格納します。次のステートメントを実行して、この方法で経度、緯度、および時間情報を格納する時空間テーブルを作成できます。
CREATE TABLE gps_data_point (id int, x double, y double, t timestamp, ship_name varchar, PRIMARY KEY(id, t));
次のいずれかの方法を使用して、軌跡ポイントをテーブルに個別に書き込みます。
時空間関数
ST_MakePoint
を使用して軌跡ポイントを構築します。たとえば、ST_MakePoint(119.073544 25.3244)
を使用して、経度が 119.073544、緯度が 25.3244 の軌跡ポイントを構築できます。INSERT INTO gps_data (id, g, t, ship_name) VALUES (1,ST_MakePoint(119.073544,25.3244), '2021-01-01 10:00:00', 'ship001'); INSERT INTO gps_data (id, g, t, ship_name) VALUES (1,ST_MakePoint(119.073544,25.3244), '2021-01-01 10:05:03', 'ship001'); INSERT INTO gps_data (id, g, t, ship_name) VALUES (1,ST_MakePoint(119.073544,25.324382), '2021-01-01 10:08:32', 'ship001'); INSERT INTO gps_data (id, g, t, ship_name) VALUES (1,ST_MakePoint(119.073536,25.324418), '2021-01-01 10:10:22', 'ship001'); INSERT INTO gps_data (id, g, t, ship_name) VALUES (2,ST_MakePoint(19.07352,25.34), '2021-01-01 08:20:21', 'ship002'); INSERT INTO gps_data (id, g, t, ship_name) VALUES (2,ST_MakePoint(19.07352,25.33), '2021-01-01 08:22:20', 'ship002');
説明ST_MakePoint
関数の詳細については、ST_MakePointをご参照ください。時空間関数
ST_GeomFromText
を使用して軌跡ポイントを構築することもできます。この関数によって構築された軌跡ポイントは、標準の Well-known Text (WKT) 形式です。ただし、ST_GeomFromText
の書き込みパフォーマンスは、ST_MakePoint
関数ほど高くありません。ST_GeomFromText
関数の詳細については、ST_GeomFromTextをご参照ください。
軌跡ポイントに関する経度、緯度、および時間情報をテーブルに書き込みます。
INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (1, 119.073544, 25.3244, '2021-01-01 10:00:00', 'ship001'); INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (1, 119.073544, 25.3244, '2021-01-01 10:05:03', 'ship001'); INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (1, 119.073544, 25.324382, '2021-01-01 10:08:32', 'ship001'); INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (1, 119.073536, 25.324418, '2021-01-01 10:10:22', 'ship001'); INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (2, 19.07352, 25.34, '2021-01-01 08:20:21', 'ship002'); INSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES (2, 19.07352, 25.33, '2021-01-01 08:22:20', 'ship002');
オプション:次のいずれかの方法を使用して、軌跡ポイントをバッチでテーブルに書き込みます。
ST_MakePoint
関数を使用して、軌跡ポイントをバッチで書き込みます。UPSERT INTO gps_data (id, g, t, ship_name) VALUES(1,ST_MakePoint(119.073544,25.3244), '2021-01-01 10:00:00', 'ship001'),(1,ST_MakePoint(119.073544,25.3244), '2021-01-01 10:05:03', 'ship001'),(1,ST_MakePoint(119.073544,25.324382), '2021-01-01 10:08:32', 'ship001'),(1,ST_MakePoint(119.073536,25.324418), '2021-01-01 10:10:22', 'ship001'),(2,ST_MakePoint(19.07352,25.34), '2021-01-01 08:20:21', 'ship002'),(2,ST_MakePoint(19.07352,25.33), '2021-01-01 08:22:20', 'ship002');
軌跡ポイントに関する経度、緯度、および時間情報をバッチで書き込みます。
UPSERT INTO gps_data_point (id, x, y, t, ship_name) VALUES(1, 119.073544, 25.3244, '2021-01-01 10:00:00', 'ship001'),(1, 119.073544, 25.3244, '2021-01-01 10:05:03', 'ship001'),(1, 119.073544, 25.324382, '2021-01-01 10:08:32', 'ship001'),(1, 119.073536, 25.324418, '2021-01-01 10:10:22', 'ship001'),(2, 19.07352, 25.34, '2021-01-01 08:20:21', 'ship002'),(2, 19.07352, 25.33, '2021-01-01 08:22:20', 'ship002');
SELECT
ステートメントを使用して、テーブルに書き込まれたデータをクエリします。テーブル内の軌跡ポイントをクエリし、時空間関数
ST_AsText
を使用してポイントを読み取り可能なテキストに変換します。SELECT id, ST_AsText(g) AS position, ship_name FROM gps_data;
次の結果が返されます。
+----+------------------------------+-----------+ | id | position | ship_name | +----+------------------------------+-----------+ | 1 | POINT (119.073544 25.3244) | ship001 | | 1 | POINT (119.073544 25.3244) | ship001 | | 1 | POINT (119.073544 25.324382) | ship001 | | 1 | POINT (119.073536 25.324418) | ship001 | | 2 | POINT (19.07352 25.34) | ship002 | | 2 | POINT (19.07352 25.33) | ship002 | +----+------------------------------+-----------+
テーブル内の軌跡ポイントに関する経度、緯度、および時間情報をクエリします。
SELECT * FROM gps_data_point;
次の結果が返されます。
+----+-------------------------------+------------+-----------+-----------+ | id | t | x | y | ship_name | +----+-------------------------------+------------+-----------+-----------+ | 1 | 2021-01-01 10:00:00 +0000 UTC | 119.073544 | 25.3244 | ship001 | | 1 | 2021-01-01 10:05:03 +0000 UTC | 119.073544 | 25.3244 | ship001 | | 1 | 2021-01-01 10:08:32 +0000 UTC | 119.073544 | 25.324382 | ship001 | | 1 | 2021-01-01 10:10:22 +0000 UTC | 119.073536 | 25.324418 | ship001 | | 2 | 2021-01-01 08:20:21 +0000 UTC | 19.07352 | 25.34 | ship002 | | 2 | 2021-01-01 08:22:20 +0000 UTC | 19.07352 | 25.33 | ship002 | +----+-------------------------------+------------+-----------+-----------+
JDBC を使用して LindormTable に接続し、データを書き込む
クエリステートメントでパラメーターを指定することにより、時空間データを LindormTable に書き込むことができます。次の Java コードは、JDBC によって提供される PreparedStatement 操作を使用して、クエリステートメントでパラメーターを指定することにより LindormTable にデータを書き込む方法の例を示しています。
// 接続を確立します。
Connection connection = DriverManager.getConnection(url, properties);
final String tableName = "testtbl"
// テーブルを作成します。
try (Statement stmt = conn.createStatement()) {
stmt.execute("create table " + tableName +
"(p1 int, c1 varchar, c2 geometry(point), constraint primary key (p1))");
}
// データの書き込みに使用するクエリステートメントを指定します。
final String upsertSql = "upsert into " + tableName + "(p1,c1,c2) values (?,?,ST_MakePoint(?,?))";
// クエリステートメントを準備します。
try (PreparedStatement preparedStatement = conn.prepareStatement(upsertSql)) {
// ステートメントのプレースホルダーに対応するパラメーターを指定します。
preparedStatement.setInt(1, 0);
preparedStatement.setString(2, "name");
preparedStatement.setDouble(3, 5.0);
preparedStatement.setDouble(4, 5.0);
// LindormTable にデータを書き込みます。
preparedStatement.executeUpdate();
}
// 接続を確立します。 // テーブルを作成します。 // データの書き込みに使用するクエリステートメントを指定します。 // クエリステートメントを準備します。 // ステートメントのプレースホルダーに対応するパラメーターを指定します。 // LindormTable にデータを書き込みます。
時空間インデックスを作成してクエリ効率を向上させる
クエリステートメントの WHERE 句で指定された条件に時空間範囲が含まれている場合は、時空間インデックスを作成してクエリを高速化できます。時空間インデックスは、Lindorm のプライマリキーインデックスとセカンダリインデックスに対応する、時空間プライマリキーインデックスと時空間セカンダリインデックスの 2 つのタイプに分類できます。詳細については、時空間インデックスの作成をご参照ください。
時空間テーブルの属性を構成します。
ALTER TABLE gps_data SET 'MUTABILITY'='MUTABLE_LATEST'; ALTER TABLE gps_data SET 'CONSISTENCY'='strong';
説明カスタムタイムスタンプに基づいて更新されるインデックスを使用するには、次のステートメントを実行して
MUTABILITY
をMUTABLE_ALL
に設定する必要があります:ALTER TABLE gps_data SET 'MUTABILITY' = 'MUTABLE_ALL';
。MUTABILITY 属性の詳細については、用語をご参照ください。時空間セカンダリインデックスを作成します。この例では、時空間テーブルがすでに作成されています。したがって、時空間セカンダリインデックスを作成するだけでクエリを高速化できます。次のステートメントは、空間列と時間列を含むインデックスを作成する方法の例を示しています。
CREATE INDEX idt ON gps_data (Z-ORDER(g,t));
指定された時空間範囲内の軌跡ポイントをクエリする
時空間関数 ST_Contains
を使用して、POLYGON ((18 24, 20 24, 20 26, 18 26, 18 24))
で指定された空間範囲と 2021-01-01 08:21:00 から 2021-01-01 08:23:00
までの時間範囲内の軌跡ポイントをクエリできます。
時空間セカンダリインデックスの Z-ORDER
関数には、空間列と時間列が含まれています。したがって、クエリ条件には空間範囲と時間範囲が含まれている必要があります。時空間クエリの最適化方法の詳細については、時空間クエリのパフォーマンスを最適化するをご参照ください。
SELECT id,t,ST_AsText(g),ship_name FROM gps_data WHERE ST_Contains(ST_GeomFromText('POLYGON ((18 24, 20 24, 20 26, 18 26, 18 24))'),g) AND t>'2021-01-01 08:21:00' AND t<'2021-01-01 08:23:00';
次の結果が返されます。
+----+-------------------------------+------------------------+-----------+
| id | t | "ST_AsText"(g) | ship_name |
+----+-------------------------------+------------------------+-----------+
| 2 | 2021-01-01 08:22:20 +0000 UTC | POINT (19.07352 25.33) | ship002 |
+----+-------------------------------+------------------------+-----------+
Lindorm GanosBase によって提供される時空間関数の詳細については、概要をご参照ください。