外部テーブル
外部テーブル機能は、特定の特殊な使用ケースを除き推奨されなくなり、将来のリリースで廃止される可能性があります。一般的なシナリオで外部データソースからのデータを管理およびクエリするには、External Catalog の使用が推奨されます。
-
v3.0以降、Hive、Iceberg、Hudiからデータをクエリするには、catalogを使用することを推奨します。詳細は Hive catalog、Iceberg catalog、Hudi catalog を参照してください。
-
v3.1以降、MySQLとPostgreSQLからデータをクエリするには JDBC catalog を、Elasticsearchからデータをクエリするには Elasticsearch catalog を使用することを推奨します。
-
v3.2.9 および v3.3.1 以降では、Oracle および SQL Server からデータをクエリするには JDBC カタログ の使用を推奨します。
-
外部テーブル機能は、StarRocksにデータをロードするために設計されており、外部システムに対して通常の操作として効率的なクエリを実行するためのものではありません。より効率的な解決策は、データをStarRocksにロードすることです。
StarRocksは、外部テーブルを使用して他のデータソースにアクセスすることをサポートしています。外部テーブルは、他のデータソースに保存されているデータテーブルに基づいて作成されます。StarRocksはデータテーブルのメタデータのみを保存します。外部テーブルを使用して、他のデータソースのデータを直接クエリすることができます。現在、 StarRocks 外部テーブル以外の外部テーブルはすべて非推奨です。別の StarRocks クラスタから現在の StarRocks クラスタにデータを書き込むことしかできません。そこからのデータの読み出しはできません。StarRocks 以外のデータソースについては、これらのデータソースからのデータの読み取りのみが可能です。
v2.5以降、StarRocksは外部データソースのホットデータクエリを高速化するData Cache機能を提供しています。詳細は Data Cache を参照してくださ い。
StarRocks外部テーブル
StarRocks 1.19以降、StarRocksはStarRocks外部テーブルを使用して、あるStarRocksクラスターから別のクラスターにデータを書き込むことを可能にしています。これにより、読み書きの分離が実現され、リソースの分離が向上します。まず、宛先StarRocksクラスターに宛先テーブルを作成します。その後、ソースStarRocksクラスターで、宛先テーブルと同じスキーマを持つStarRocks外部テーブルを作成し、PROPERTIESフィールドに宛先クラスターとテーブルの情報を指定します。
データは、INSERT INTOステートメントを使用してStarRocks外部テーブルに書き込むことで、ソースクラスターから宛先クラスターに書き込むことができます。これにより、以下の目標を実現できます:
- 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 | 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で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は、JSON関連の関数を使用してNESTEDタイプのデータを読み取ります。
- Elasticsearchは多次元配列を自動的に一次元配列にフラット化します。StarRocksも同様です。ElasticsearchからのARRAYデータのクエリサポートはv2.5から追加されました。