外部テーブル
-
v3.0以降、Hive、Iceberg、Hudiからデータをクエリするために、catalogを使用することを推奨します。詳細は Hive catalog、Iceberg catalog、Hudi catalog を参照してください。
-
v3.1以降、MySQLとPostgreSQLからデータをクエリするために JDBC catalog を使用し、Elasticsearchからデータをクエリするために Elasticsearch catalog を使用することを推奨します。
-
外部テーブル機能は、StarRocksにデータをロードするために設計されており、通常の操作として外部システムに対して効率的なクエリを実行するためのものではありません。より効率的な解決策は、データをStarRocksにロードすることです。
StarRocksは、外部 テーブルを使用して他のデータソースにアクセスすることをサポートしています。外部テーブルは、他のデータソースに保存されているデータテーブルに基づいて作成されます。StarRocksはデータテーブルのメタデータのみを保存します。外部テーブルを使用して、他のデータソースのデータを直接クエリすることができます。StarRocksは以下のデータソースをサポートしています: MySQL、StarRocks、Elasticsearch、Apache Hive™、Apache Iceberg、Apache Hudi。現在、他のStarRocksクラスターから現在のStarRocksクラスターにデータを書き込むことのみが可能です。データを読み取ることはできません。StarRocks以外のデータソースからは、これらのデータソースからデータを読み取ることのみが可能です。
2.5以降、StarRocksは外部データソース上のホットデータクエリを高速化するData Cache機能を提供しています。詳細は Data Cache を参照してください。
StarRocks外部テーブル
StarRocks 1.19以降、StarRocksはStarRocks外部テーブルを使用して、あるStarRocksクラスターから別のクラスターにデータを書き込むことを可能にしています。これにより、読み書きの分離が実現され、リソースの分離が向上します。まず、宛先のStarRocksクラスターに宛先テーブルを作成します。次に、ソースのStarRocksクラスターで、宛先テーブルと同じスキーマを持つStarRocks外部テーブルを作成し、PROPERTIESフィールドに宛先クラスターとテーブルの情報を指定します。
データは、StarRocks外部テーブルにデータを書き込むためのINSERT INTOステートメントを使用して、ソースクラスターから宛先クラスターに書き込むことができます。これにより、以下の目標を実現できます:
- StarRocksクラスター間のデータ同期。
- 読み書きの分離。データはソースクラスターに書き込まれ、ソースクラスターからのデータ変更は宛先クラスターに同期され、クエリサービスを提供します。
以下のコードは、宛先テーブルと外部テーブルを作成する方法を示しています。
# 宛先のStarRocksクラスターに宛先テーブルを作成します。
CREATE TABLE t
(
k1 DATE,
k2 INT,
k3 SMALLINT,
k4 VARCHAR(2048),
k5 DATETIME
)
ENGINE=olap
DISTRIBUTED BY HASH(k1);
# ソースのStarRocksクラスターに外部テーブルを作成します。
CREATE EXTERNAL TABLE external_t
(
k1 DATE,
k2 INT,
k3 SMALLINT,
k4 VARCHAR(2048),
k5 DATETIME
)
ENGINE=olap
DISTRIBUTED BY HASH(k1)
PROPERTIES
(
"host" = "127.0.0.1",
"port" = "9020",
"user" = "user",
"password" = "passwd",
"database" = "db_test",
"table" = "t"
);
# ソースクラスターから宛先クラスターにデータを書き込むために、StarRocks外部テーブルにデータを書き込みます。2番目のステートメントは本番環境で推奨されます。
insert into external_t values ('2020-10-11', 1, 1, 'hello', '2020-10-11 10:00:00');
insert into external_t select * from other_table;
パラメータ:
-
EXTERNAL: このキーワードは、作成されるテーブルが外部テーブルであることを示します。
-
host: このパラメータは、宛先StarRocksクラスターのLeader FEノードのIPアドレスを指定します。
-
port: このパラメータは、宛先StarRocksクラスターのFEノードのRPCポートを指定します。
注記StarRocks外部テーブルが属するソースクラスターが宛先StarRocksクラスターにアクセスできるようにするためには、ネットワークとファイアウォールを設定して、以下のポートへのアクセスを許可する必要があります:
- FEノードのRPCポート。FE設定ファイル fe/fe.conf の
rpc_portを参照してください。デフォルトのRPCポートは9020です。 - BEノードのbRPCポート。BE設定ファイル be/be.conf の
brpc_portを参照してください。デフォルトのbRPCポートは8060です。
- FEノードのRPCポート。FE設定ファイル fe/fe.conf の
-
user: このパラメータは、宛先StarRocksクラスターにアクセスするために使用されるユーザー名を指定します。
-
password: このパラメータは、宛先StarRocksクラスターにアクセスするために使用されるパスワードを指定します。
-
database: このパラメータは、宛先テーブルが属するデータベースを指定します。
-
table: このパラメータは、宛先テーブルの名前を指定します。
StarRocks外部テーブルを使用する際の制限事項は以下の通りです:
- StarRocks外部テーブルでは、INSERT INTOとSHOW CREATE TABLEコマンドのみを実行できます。他のデータ書き込み方法はサポートされていません。また、StarRocks外部テーブルからデータをクエリしたり、外部テーブルに対してDDL操作を行うことはできません。
- 外部テーブルの作成構文は通常のテーブルの作成と同じですが、外部テーブルのカラム名やその他の情報は宛先テーブルと同じでなければなりません。
- 外部テーブルは、宛先テーブルから10秒ごとにテーブルメタデータを同期します。宛先テーブルでDDL操作が行われた場合、2つのテーブル間でデータ同期に遅延が生じる可能性があります。
JDBC互換データベース用外部テーブル
v2.3.0以降、StarRocksはJDBC互換データベースをクエリするための外部テーブルを提供しています。これにより、データをStarRocksにインポートすることなく、これらのデータベースのデータを非常に高速に分析することができます。このセクションでは、StarRocksで外部テーブルを作成し、JDBC互換データベースのデータをクエリする方法について説明します。
前提条件
JDBC外部テーブルを使用してデータをクエリする前に、FEsとBEsがJDBCドライバのダウンロードURLにアクセスできることを確認してくださ い。ダウンロードURLは、JDBCリソースを作成するためのステートメントで指定される driver_url パラメータによって指定されます。
JDBCリソースの作成と管理
JDBCリソースの作成
データベースからデータをクエリするための外部テーブルを作成する前に、StarRocksでJDBCリソースを作成してデータベースの接続情報を管理する必要があります。データベースはJDBCドライバをサポートしている必要があり、「ターゲットデータベース」と呼ばれます。リソースを作成した後、それを使用して外部テーブルを作成できます。
以下のステートメントを実行して、jdbc0 という名前のJDBCリソースを作成します。
CREATE EXTERNAL RESOURCE jdbc0
PROPERTIES (
"type"="jdbc",
"user"="postgres",
"password"="changeme",
"jdbc_uri"="jdbc:postgresql://127.0.0.1:5432/jdbc_test",
"driver_url"="https://repo1.maven.org/maven2/org/postgresql/postgresql/42.3.3/postgresql-42.3.3.jar",
"driver_class"="org.postgresql.Driver"
);
PROPERTIESで必要なパラメータは以下の通りです:
-
type: リソースのタイプ。値をjdbcに設定します。 -
user: ターゲットデータベースに接続するために使用されるユーザー名。 -
password: ターゲットデータベースに接続するために使用されるパスワード。 -
jdbc_uri: JDBCドライバがターゲットデータベースに接続するために使用するURI。URIの形式はデータベースURIの構文を満たす必要があります。一般的なデータベースのURI構文については、Oracle、PostgreSQL、SQL Serverの公式ウェブサイトを参照してください。
注: URIにはターゲットデータベースの名前を含める必要があります。例えば、前述のコード例では、
jdbc_testが接続したいターゲットデータベースの名前です。
-
driver_url: JDBCドライバJARパッケージのダウンロードURL。HTTP URLまたはファイルURLがサポートされています。例えば、https://repo1.maven.org/maven2/org/postgresql/postgresql/42.3.3/postgresql-42.3.3.jarまたはfile:///home/disk1/postgresql-42.3.3.jar。 -
driver_class: JDBCドライバのクラス名。一般的なデータベースのJDBCドライバクラス名は以下の通りです:- MySQL: com.mysql.jdbc.Driver (MySQL 5.x以前)、com.mysql.cj.jdbc.Driver (MySQL 6.x以降)
- SQL Server: com.microsoft.sqlserver.jdbc.SQLServerDriver
- Oracle: oracle.jdbc.driver.OracleDriver
- PostgreSQL: org.postgresql.Driver
リソースが作成されると、FEはdriver_urlパラメータで指定されたURLを使用してJDBCドライバJARパッケージをダウンロードし、チェックサムを生成し、BEsがダウンロードしたJDBCドライバを検証するためにチェックサムを使用します。
注: JDBCドライバJARパッケージのダウンロードに失敗した場合、リソースの作成も失敗します。
BEsがJDBC外部テーブルを初めてクエリし、対応するJDBCドライバJARパッケージがマシン上に存在しない場合、BEsはdriver_urlパラメータで指定されたURLを使用してJDBCドライバJARパッケージをダウンロードし、すべてのJDBCドライバJARパッケージは${STARROCKS_HOME}/lib/jdbc_driversディレクトリに保存されます。
JDBCリソースの表示
以下のステートメントを実行して、StarRocks内のすべてのJDBCリソースを表示します。
SHOW RESOURCES;
注:
ResourceType列はjdbcです。
JDBCリソースの削除
以下のステートメントを実行して、jdbc0という名前のJDBCリソースを削除します。
DROP RESOURCE "jdbc0";
注: JDBCリソースが削除されると、そのJDBCリソースを使用して作成されたすべてのJDBC外部テーブルが使用できなくなります。ただし、ターゲットデータベース内のデータは失われません。ターゲットデータベース内のデータをStarRocksでクエリする必要がある場合は、JDBCリソースとJDBC外部テーブルを再作成することができます。
データベースの作成
以下のステートメントを実行して、StarRocks内にjdbc_testという名前のデータベースを作成し、アクセスします。
CREATE DATABASE jdbc_test;
USE jdbc_test;
注: 前述のステートメントで指定するデータベース名は、ターゲットデータベースの名前と同じである必要はありません。
JDBC外部テーブルの作成
以下のステートメントを実行して、jdbc_testデータベース内にjdbc_tblという名前のJDBC外部テーブルを作成します。
create external table jdbc_tbl (
`id` bigint NULL,
`data` varchar(200) NULL
) ENGINE=jdbc
properties (
"resource" = "jdbc0",
"table" = "dest_tbl"
);
propertiesで必要なパラメータは以下の通りです:
-
resource: 外部テーブルの作成に使用されるJDBCリソースの名前。 -
table: データベース内のターゲットテーブル名。
StarRocksとターゲットデータベース間のサポートされるデータ型とデータ型のマッピングについては、[Data type mapping](External_table.md#Data type mapping)を参照してください。
注:
- インデックスはサポートされていません。
- PARTITION BYまたはDISTRIBUTED BYを使用してデータ分布ルールを指定することはできません。
JDBC外部テーブルのクエリ
JDBC外部テーブルをクエリする前に、以下のステートメントを実行してPipelineエンジンを有効にする必要があります。
set enable_pipeline_engine=true;
注: Pipelineエンジンがすでに有効になっている場合、このステップをスキップできます。
以下のステートメントを実行して、JDBC外部テーブルを使用してターゲットデータベース内のデータをクエリします。
select * from JDBC_tbl;
StarRocksは、フィルター条件をターゲットテーブルにプッシュダウンすることで、述語プッシュダウンをサポートしています。データソースにできるだけ近い場所でフィルター条件を実行することで、クエリパフォーマンスを向上させることができます。現在、StarRocksは、バイナリ比較演算子(>, >=, =, <, <=)、IN、IS NULL、BETWEEN ... AND ...を含む演算子をプッシュダウンできます。ただし、StarRocksは関数をプッシュダウンすることはできません。
データ型のマッピング
現在、StarRocksはターゲットデータベースの基本型のデータのみをクエリできます。例えば、NUMBER、STRING、TIME、DATEなどです。ターゲットデータベースのデータ値の範囲がStarRocksでサポートされていない場合、クエリはエラーを報告します。
ターゲットデータベースとStarRocksの間のマッピングは、ターゲットデータベースのタイプに基づいて異なります。
MySQLとStarRocks
| MySQL | StarRocks |
|---|---|
| BOOLEAN | BOOLEAN |
| TINYINT | TINYINT |
| SMALLINT | SMALLINT |
| MEDIUMINTINT | INT |
| BIGINT | BIGINT |
| FLOAT | FLOAT |
| DOUBLE | DOUBLE |
| DECIMAL | DECIMAL |
| CHAR | CHAR |
| VARCHAR | VARCHAR |
| DATE | DATE |
| DATETIME | DATETIME |
OracleとStarRocks
| Oracle | StarRocks |
|---|---|
| CHAR | CHAR |
| VARCHARVARCHAR2 | VARCHAR |
| DATE | DATE |
| SMALLINT | SMALLINT |
| INT | INT |
| BINARY_FLOAT | FLOAT |
| BINARY_DOUBLE | DOUBLE |
| DATE | DATE |
| DATETIME | DATETIME |
| NUMBER | DECIMAL |
PostgreSQLとStarRocks
| PostgreSQL | StarRocks |
|---|---|
| SMALLINTSMALLSERIAL | SMALLINT |
| INTEGERSERIAL | INT |
| BIGINTBIGSERIAL | BIGINT |
| BOOLEAN | BOOLEAN |
| REAL | FLOAT |
| DOUBLE PRECISION | DOUBLE |
| DECIMAL | DECIMAL |
| TIMESTAMP | DATETIME |
| DATE | DATE |
| CHAR | CHAR |
| VARCHAR | VARCHAR |
| TEXT | VARCHAR |
SQL ServerとStarRocks
| SQL Server | StarRocks |
|---|---|
| BOOLEAN | BOOLEAN |
| TINYINT | TINYINT |
| SMALLINT | SMALLINT |
| INT | INT |
| BIGINT | BIGINT |
| FLOAT | FLOAT |
| REAL | DOUBLE |
| DECIMALNUMERIC | DECIMAL |
| CHAR | CHAR |
| VARCHAR | VARCHAR |
| DATE | DATE |
| DATETIMEDATETIME2 | DATETIME |
制限事項
-
JDBC外部テーブルを作成する際、テーブルにインデックスを作成したり、PARTITION BYやDISTRIBUTED BYを使用してテーブルのデータ分布ルールを指定することはできません。
-
JDBC外部テーブルをクエリする際、StarRocksは関数をテーブルにプッシュダウンすることができません。
(非推奨) Elasticsearch外部テーブル
StarRocksとElasticsearchは、2つの人気のある分析システムです。StarRocksは大規模な分散コンピューティングにおいて高いパフォーマンスを発揮し、Elasticsearchは全文検索に最適です。StarRocksとElasticsearchを組み合わせることで、より完全なOLAPソリューションを提供できます。
Elasticsearch外部テーブルの作成例
構文
CREATE EXTERNAL TABLE elastic_search_external_table
(
k1 DATE,
k2 INT,
k3 SMALLINT,
k4 VARCHAR(2048),
k5 DATETIME
)
ENGINE=ELASTICSEARCH
PROPERTIES (
"hosts" = "http://192.168.0.1:9200,http://192.168.0.2:9200",
"user" = "root",
"password" = "root",
"index" = "tindex",
"type" = "_doc",
"es.net.ssl" = "true"
);
以下の表は、パラメータを説明しています。
| パラメータ | 必須 | デフォルト値 | 説明 |
|---|---|---|---|
| hosts | はい | なし | Elasticsearchクラスターの接続アドレス。1つ以上のアドレスを指定できます。StarRocksはこのアドレスからElasticsearchのバージョンとインデックスシャードの割り当てを解析します。StarRocksは、GET /_nodes/http API操作によって返されるアドレスに基づいてElasticsearchクラスターと通信します。したがって、hostパラメータの値は、GET /_nodes/http API操作によって返されるアドレスと同じでなければなりません。そうでない場合、BEsはElasticsearchクラスターと通信できない可能性があります。 |
| index | はい | なし | StarRocksに作成されたテーブル上のElasticsearchインデックスの名前。名前はエイリアスであることができます。このパラメータはワイルドカード(*)をサポートします。例えば、indexをhello*に設定すると、StarRocksは名前がhelloで始まるすべてのインデックスを取得します。 |
| user | いいえ | 空 | 基本認証が有効なElasticsearchクラスターにログインするために使用されるユーザー名。/*cluster/state/*nodes/httpおよびインデックスへのアクセス権があることを確認してください。 |
| password | いいえ | 空 | Elasticsearchクラスターにログインするために使用されるパスワード。 |
| type | いいえ | _doc | インデックスのタイプ。デフォルト値: _doc。Elasticsearch 8以降のバージョンでデータをクエリする場合、このパラメータを設定する必要はありません。Elasticsearch 8以降のバージョンではマッピングタイプが削除されています。 |
| es.nodes.wan.only | いいえ | false | StarRocksがElasticsearchクラスターにアクセスしてデータを取得するためにhostsで指定されたアドレスのみを使用するかどうかを指定します。
|
| es.net.ssl | いいえ | false | ElasticsearchクラスターにアクセスするためにHTTPSプロトコルを使用できるかどうかを指定します。StarRocks 2.4以降のバージョンのみがこのパラメータの設定をサポートしています。
|
| enable_docvalue_scan | いいえ | true | Elasticsearchの列指向ストレージからターゲットフィールドの値を取得するかどうかを指定します。ほとんどの場合、列指向ストレージからデータを読み取る方が行指向ストレージからデータを読み取るよりも優れています。 |
| enable_keyword_sniff | いいえ | true | ElasticsearchでTEXT型フィールドをKEYWORD型フィールドに基づいてスニッフするかどうかを指定します。このパラメータをfalseに設定すると、StarRocksはトークン化後にマッチングを実行します。 |
より高速なクエリのための列指向スキャン
enable_docvalue_scanをtrueに設定すると、StarRocksはElasticsearchからデータを取得する際に以下のルールに従います:
- 試してみる: StarRocksはターゲットフィールドに対して列指向ストレージが有効かどうかを自動的に確認します。有効である場合、StarRocksはターゲットフィールドのすべての値を列指向ストレージから取得します。
- 自動ダウングレード: ターゲットフィールドのいずれかが列指向ストレージで利用できない場合、StarRocksは行指向ストレージ(
_source)からターゲットフィー ルドのすべての値を解析して取得します。
注意
- ElasticsearchのTEXT型フィールドには列指向ストレージが利用できません。したがって、TEXT型の値を含むフィールドをクエリする場合、StarRocksはフィールドの値を
_sourceから取得します。- 多数のフィールド(25以上)をクエリする場合、
docvalueからフィールド値を読み取ることは、_sourceからフィールド値を読み取ることと比較して顕著な利点を示しません。
KEYWORD型フィールドのスニッフ
enable_keyword_sniffをtrueに設定すると、Elasticsearchはインデックスなしで直接データ取り込みを許可します。取り込み後に自動的にインデックスを作成します。STRING型フィールドの場合、ElasticsearchはTEXT型とKEYWORD型の両方を持つフィールドを作成します。これはElasticsearchのマルチフィールド機能の動作です。マッピングは以下の通りです:
"k4": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
例えば、k4に対して"="フィルタリングを行う場合、StarRocks on Elasticsearchはフィルタリング操作をElasticsearchのTermQueryに変換します。
元のSQLフィルターは以下の通りです:
k4 = "StarRocks On Elasticsearch"
変換されたElasticsearchクエリDSLは以下の通りです:
"term" : {
"k4": "StarRocks On Elasticsearch"
}
k4の最初のフィールドはTEXTであり、データ取り込み後にk4に設定されたアナライザー(またはアナライザーが設定されていない場合は標準アナライザー)によってトークン化されます。その結果、最初のフィールドは3つの用語にトークン化されます: StarRocks, On, Elasticsearch。詳細は以下の通りです:
POST /_analyze
{
"analyzer": "standard",
"text": "StarRocks On Elasticsearch"
}
トークン化の結果は以下の通りです:
{
"tokens": [
{
"token": "starrocks",
"start_offset": 0,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "on",
"start_offset": 6,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "elasticsearch",
"start_offset": 9,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 2
}
]
}
次のようなクエリを実行するとします:
"term" : {
"k4": "StarRocks On Elasticsearch"
}
辞書にStarRocks On Elasticsearchに一致する用語がないため、結果は返されません。
しかし、enable_keyword_sniffをtrueに設定している場合、StarRocksはk4 = "StarRocks On Elasticsearch"をk4.keyword = "StarRocks On Elasticsearch"に変換してSQLセマンティクスに一致させます。変換されたStarRocks On ElasticsearchクエリDSLは以下の通りです:
"term" : {
"k4.keyword": "StarRocks On Elasticsearch"
}
k4.keywordはKEYWORD型です。したがって、データはElasticsearchに完全な用語として書き込まれ、正常に一致します。
カラムデータ型のマッピング
外部テーブルを作成する際、Elasticsearchテーブルのカラムデータ型に基づいて外部テーブルのカラムデータ型を指定する必要があります。以下の表はカラムデータ型のマッピングを示しています。
| Elasticsearch | StarRocks |
|---|---|
| BOOLEAN | BOOLEAN |
| BYTE | TINYINT/SMALLINT/INT/BIGINT |
| SHORT | SMALLINT/INT/BIGINT |
| INTEGER | INT/BIGINT |
| LONG | BIGINT |
| FLOAT | FLOAT |
| DOUBLE | DOUBLE |
| KEYWORD | CHAR/VARCHAR |
| TEXT | CHAR/VARCHAR |
| DATE | DATE/DATETIME |
| NESTED | CHAR/VARCHAR |
| OBJECT | CHAR/VARCHAR |
| ARRAY | ARRAY |
注意
- StarRocksは、NESTED型のデータをJSON関連の関数を使用して読み取ります。
- Elasticsearchは多次元配列を自動的に一次元配列にフラット化します。StarRocksも同様です。ElasticsearchからのARRAYデータのクエリサポートはv2.5から追加されました。
述語プッシュダウン
StarRocksは述語プッシュダウンをサポートしています。フィルターはElasticsearchにプッシュダウンされて実行され、クエリパフォーマンスを向上させます。以下の表は述語プッシュダウンをサポートする演算子を示しています。
| SQL構文 | ES構文 |
|---|---|
= | term query |
in | terms query |
>=, <=, >, < | range |
and | bool.filter |
or | bool.should |
not | bool.must_not |
not in | bool.must_not + terms |
esquery | ES Query DSL |
例
esquery関数は、SQLで表現できないクエリ(例えば、matchやgeoshape)をElasticsearchにプッシュダウンしてフィルタリングするために使用されます。esquery関数の最初のパラメータはインデックスを関連付けるために使用されます。2番目のパラメータは、で囲まれた基本的なQuery DSLのJSON式です。JSON式には1つのルートキーが必要ですが、1つだけです。例えば、match、geo_shape、またはboolです。
- matchクエリ
select * from es_table where esquery(k4, '{
"match": {
"k4": "StarRocks on elasticsearch"
}
}');
- geo関連クエリ
select * from es_table where esquery(k4, '{
"geo_shape": {
"location": {
"shape": {
"type": "envelope",
"coordinates": [
[
13,
53
],
[
14,
52
]
]
},
"relation": "within"
}
}
}');
- boolクエリ
select * from es_table where esquery(k4, ' {
"bool": {
"must": [
{
"terms": {
"k1": [
11,
12
]
}
},
{
"terms": {
"k2": [
100
]
}
}
]
}
}');
使用上の注意
- Elasticsearch 5.x以前のバージョンは、5.x以降のバージョンとは異なる方法でデータをスキャンします。現在、5.x以降のバージョンのみがサポートされています。
- HTTP基本認証が有効なElasticsearchクラスターがサポートされています。
- StarRocksからデータをクエリすることは、Elasticsearchから直接データをクエリすることほど速くないかもしれません。例えば、カウント関連のクエリです。その理由は、Elasticsearchがターゲットドキュメントのメタデータを直接読み取り、実際のデータをフィルタリングする必要がないため、カウントクエリが高速化されるからです。