外部テーブル
-
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外部テーブルを除くすべての外部テーブルは非推奨です。他の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"
);
以下の表は、パラメータを説明しています。
| Parameter | Required | Default value | Description |
|---|---|---|---|
| hosts | Yes | None | Elasticsearchクラスターの接続アドレス。1つ以上のアドレスを指定できます。StarRocksはこのアドレスからElasticsearchのバージョンとインデックスシャードの割り当てを解析します。StarRocksは、GET /_nodes/http API操作によって返されるアドレスに基づいてElasticsearchクラスターと通信します。したがって、hostパラメータの値は、GET /_nodes/http API操作によって返されるアドレスと同じでなければなりません。そうでない場合、BEsはElasticsearchクラスターと通信できない可能性があります。 |
| index | Yes | None | StarRocksのテーブルに作成されたElasticsearchインデックスの名前。名前はエイリアスにすることができます。このパラメータはワイルドカード(*)をサポートしています。たとえば、indexをhello*に設定すると、StarRocksはhelloで始まるすべてのインデックスを取得します。 |
| user | No | Empty | 基本認証が有効なElasticsearchクラスターにログインするために使用されるユーザー名。/*cluster/state/*nodes/httpとインデックスにアクセスできることを確認し てください。 |
| password | No | Empty | Elasticsearchクラスターにログインするために使用されるパスワード。 |
| type | No | _doc | インデックスのタイプ。デフォルト値:_doc。Elasticsearch 8以降のバージョンでデータをクエリする場合、このパラメータを設定する必要はありません。Elasticsearch 8以降のバージョンではマッピングタイプが削除されています。 |
| es.nodes.wan.only | No | false | StarRocksがElasticsearchクラスターにアクセスしてデータを取得するためにhostsで指定されたアドレスのみを使用するかどうかを指定します。
|
| es.net.ssl | No | false | ElasticsearchクラスターにアクセスするためにHTTPSプロトコルを使用できるかどうかを指定します。StarRocks 2.4以降のバージョンのみでこのパラメータの設定をサポートしています。
|
| enable_docvalue_scan | No | true | Elasticsearchの列指向(カラムナ)ストレージからターゲットフィールドの値を取得するかどうかを指定します。ほとんどの場合、列指向(カラムナ)ストレージからデータを読み取る方が行指向(ロウ)ストレージから読み取るよりも優れています。 |
| enable_keyword_sniff | No | true | ElasticsearchでKEYWORDタイプのフィールドに基づいてTEXTタイプのフィールドをスニッフするかどうかを指定します。このパラメータを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に完全な用語として書き込まれ、成功したマッチングが可能になります。