このトピックでは、Object Storage Service (OSS) の JSON 形式の外部テーブルを作成、読み取り、書き込みする方法について説明します。
前提条件
Alibaba Cloud アカウント、RAM ユーザー、または RAM ロールには、OSS 外部テーブルにアクセスするために必要な権限が必要です。権限付与の詳細については、「OSS の STS 権限付与」をご参照ください。
(オプション) OSS バケット、OSS ディレクトリ、および OSS データファイルを作成済みであること。詳細については、「バケットの作成」、「ディレクトリの管理」、および「簡易アップロード」をご参照ください。
MaxCompute は OSS にディレクトリを自動的に作成できます。単一の SQL 文を使用して、外部テーブルと UDF の両方を含む読み取りおよび書き込み操作を実行できます。手動でのディレクトリ作成は不要になりましたが、従来の方法も引き続きサポートされています。
MaxCompute プロジェクトを作成済みであること。詳細については、「MaxCompute プロジェクトの作成」をご参照ください。
MaxCompute は特定のリージョンにのみデプロイされます。リージョン間のデータ接続性の問題を回避するため、MaxCompute プロジェクトと同じリージョンにあるバケットを使用してください。
Alibaba Cloud アカウントまたは RAM ユーザーが、プロジェクトに対する CreateTable 権限を持っていること。テーブル操作の権限の詳細については、「MaxCompute の権限」をご参照ください。
制限事項
OSS 外部テーブルでは、クラスタープロパティはサポートされていません。
単一のファイルは 3 GB を超えることはできません。ファイルが 3 GB を超える場合は、分割する必要があります。
使用上の注意
ファイルに外部テーブルよりも多くの列が含まれている場合、余分な列は破棄されます。
データ型のサポート
MaxCompute のデータの型の詳細については、「データ型 (V1.0)」および「データ型 (V2.0)」をご参照ください。
データの型 | サポート済み | データの型 | サポート済み |
TINYINT | STRING | ||
SMALLINT | DATE | ||
INT | DATETIME | ||
BIGINT | TIMESTAMP | ||
BINARY | TIMESTAMP_NTZ | ||
FLOAT | BOOLEAN | ||
DOUBLE | ARRAY | ||
DECIMAL(precision,scale) | MAP | ||
VARCHAR(n) | STRUCT | ||
CHAR(n) | JSON |
外部テーブルの作成
構文
簡易構文
CREATE EXTERNAL TABLE <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS textfile
LOCATION '<oss_location>';完全な構文
CREATE EXTERNAL TABLE <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
[WITH serdeproperties (
['<property_name>'='<property_value>',...])
]
STORED AS textfile
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];共通パラメーター
詳細については、「基本構文パラメーター」をご参照ください。
固有パラメーター
tblproperties パラメーター
property_name | シナリオ | 説明 | property_value | デフォルト値 |
mcfed.mapreduce.output.fileoutputformat.compress | OSS への書き込み時に TEXTFILE データを圧縮するかどうかを指定します。 | TEXTFILE 圧縮プロパティ。OSS への書き込み時に TEXTFILE データファイルを圧縮するかどうかを指定します。このプロパティを True に設定すると、MaxCompute は TEXTFILE データファイルを圧縮形式で OSS に書き込みます。それ以外の場合、ファイルは圧縮されません。 |
| False |
mcfed.mapreduce.output.fileoutputformat.compress.codec | OSS への書き込み時に TEXTFILE データを圧縮するかどうかを指定します。 | TEXTFILE 圧縮プロパティ。TEXTFILE データファイルの圧縮メソッドを指定します。デフォルトでは、ファイルは 注: |
| org.apache.hadoop.io.compress.DeflateCodec |
odps.external.data.output.prefix (odps.external.data.prefix と互換性あり) | 出力ファイル名のカスタムプレフィックスを指定します。 |
| 'mc_' など、要件を満たす文字列。 | なし |
odps.external.data.enable.extension | 出力ファイルのファイル名拡張子を表示するかどうかを指定します。 | このプロパティを True に設定すると、出力ファイルの拡張子が表示されます。それ以外の場合、拡張子は表示されません。 |
| False |
odps.external.data.output.suffix | 出力ファイル名のカスタムサフィックスを指定します。 | サフィックスには、文字 (a-z および A-Z)、数字 (0-9)、およびアンダースコア (_) のみを含めることができます。 | '_hangzhou' など、要件を満たす文字列。 | なし |
odps.external.data.output.explicit.extension | 出力ファイルのカスタム拡張子を指定します。 |
| "jsonl" など、要件を満たす文字列。 | なし |
使用上の注意
JSON 外部テーブルを作成する際、フィールドにネストされた JSON オブジェクト (フィールドの値が JSON 構造体) が含まれている場合、このフィールドのデータの型を STRING または JSON として定義しないでください。そうしないと、システムはサブフィールドを自動的に解析できません。次のいずれかのメソッドを使用できます:
フィールドを STRING として定義します。データをクエリする際、必要に応じて
get_json_objectなどの関数を使用して、内部サブフィールドのコンテンツを抽出できます。STRUCT 型を使用してフィールドの構造を定義できます。これにより、JSON オブジェクトのサブフィールドがテーブル内の個別のサブ列にマッピングされます。その後、
field_name.subfield_nameフォーマットを使用して内部データに直接アクセスできます。
これらの操作の詳細については、「例 2」をご参照ください。
データの書き込み
MaxCompute から OSS にデータを書き込む構文の詳細については、「OSS へのデータの書き込み」をご参照ください。
データのクエリと分析
SELECT 構文の詳細については、「OSS からのデータの読み取り」をご参照ください。
クエリプランの最適化の詳細については、「クエリの最適化」をご参照ください。
例
例 1: JSON 外部テーブルの作成、書き込み、クエリ
この例では、組み込みのオープンソースデータパーサを使用して JSON 形式の外部テーブルを作成し、OSS にデータを書き込み、データをクエリする方法を示します。
データを準備します。
OSS コンソールにログインし、テストデータファイル json2025.txt を OSS バケットの
external-table-test/json/dt=20250521/フォルダにアップロードします。詳細については、「ファイルのアップロード」をご参照ください。JSON 形式の外部テーブルを作成します。
CREATE EXTERNAL TABLE mc_oss_extable_name_json ( action STRING, time STRING ) PARTITIONED BY (dt STRING) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/external-table-test/json/';パーティションを検出して登録します。作成した OSS 外部テーブルがパーティションテーブルである場合、追加のコマンドを実行して OSS ディレクトリからパーティションを登録する必要があります。詳細については、「OSS 外部テーブルにパーティションデータを追加するための構文」をご参照ください。
-- パーティションを検出して登録します。 MSCK REPAIR TABLE mc_oss_extable_name_json ADD PARTITIONS;JSON 外部テーブルからデータを読み取ります。
SELECT * FROM mc_oss_extable_name_json WHERE dt=20250526;次の結果が返されます:
+------------+------------+------------+ | action | time | dt | +------------+------------+------------+ | Close | 1469679568 | 20250526 | | Close | 1469679568 | 20250526 | +------------+------------+------------+JSON 外部テーブルにデータを書き込みます。
INSERT INTO mc_oss_extable_name_json PARTITION (dt='20250526') VALUES ('test','1627273823');書き込まれたデータを表示します。
SELECT * FROM mc_oss_extable_name_json WHERE dt=20250526;次の結果が返されます:
+------------+------------+------------+ | action | time | dt | +------------+------------+------------+ | test | 1627273823 | 20250526 | | Close | 1469679568 | 20250526 | | Close | 1469679568 | 20250526 | +------------+------------+------------+
例 2: JSON 形式のフィールドから値を読み取る
データの準備
JSON データファイル events.json を作成します:
{"a":{"x":1, "y":2}, "id":"123"}
{"a":{"x":3, "y":4}, "id":"345"}OSS コンソールにログインし、テストデータを OSS バケットの external-table-test/json-struct/ フォルダにアップロードします。詳細については、「ファイルのアップロード」をご参照ください。
方法 1: TEXTFILE 外部テーブルを作成し、get_json_object 関数を使用してフィールド値を読み取る
string型の列を 1 つだけ含む TEXTFILE 外部テーブルを作成します:CREATE EXTERNAL TABLE extable_json_test01 ( col STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\n' STORED AS textfile LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/external-table-test/json_struct/'; SELECT * FROM extable_json_test01;次の結果が返されます:
+------------------------------------+ | col | +------------------------------------+ | {"a": {"x": 1, "y": 2},"id":"123"} | | {"a": {"x": 3, "y": 4},"id":"345"} | +------------------------------------+get_json_object関数を使用して、aおよびidフィールドを読み取ることができます:SELECT get_json_object(col, '$.a') AS a, get_json_object(col, '$.id') AS id FROM extable_json_test01;次の結果が返されます:
+-------------------+-----+ | a | id | +-------------------+-----+ | {"x":1,"y":2} | 123 | | {"x":3,"y":4} | 345 | +-------------------+-----+ネストされたフィールド
x、y、およびidを読み取ることができます:SELECT get_json_object(get_json_object(col,'$.a'),'$.x') AS x, get_json_object(get_json_object(col,'$.a'),'$.y') AS y, get_json_object(col,'$.id') AS id FROM extable_json_test01;次の結果が返されます:
+---+---+-----+ | x | y | id | +---+---+-----+ | 1 | 2 |123 | | 3 | 4 |345 | +---+---+-----+
方法 2: JSON 外部テーブルを作成し、STRUCT 型を使用してデータ構造を定義する
JSON 形式の外部テーブルを作成し、
STRUCT型を使用してネストされたフィールドを定義します:CREATE EXTERNAL TABLE extable_json_test02 ( a STRUCT<x: BIGINT, y: BIGINT>, id STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' STORED AS textfile LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/external-table-test/json_struct/';テーブルのコンテンツを直接クエリできます:
SELECT * FROM extable_json_test02;次の結果が返されます:
+----------+-----+ | a | id | +----------+-----+ | {x:1, y:2}|123 | | {x:3, y:4}|345 | +----------+-----+また、
get_json_objectおよびTO_JSON関数を使用して、xおよびyフィールドを読み取ることもできます:SELECT get_json_object(TO_JSON(a), '$.x') AS x, get_json_object(TO_JSON(a), '$.y') AS y, id FROM extable_json_test02;次の結果が返されます:
+---+---+-----+ | x | y | id | +---+---+-----+ | 1 | 2 |123 | | 3 | 4 |345 | +---+---+-----+
例 3: 出力 OSS ファイルのプレフィックス、サフィックス、および拡張子を設定する
出力 OSS ファイルのカスタムプレフィックスを
test06_に設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムプレフィックスを設定します。 'odps.external.data.output.prefix'='test06_') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルのカスタムサフィックスを
_beijingに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムサフィックスを設定します。 'odps.external.data.output.suffix'='_beijing') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルの拡張子が自動的に生成されます。DDL 文は次のとおりです:
CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- 拡張子を自動的に生成します。 'odps.external.data.enable.extension'='true') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。
出力 OSS ファイルのカスタム拡張子を
jsonlに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタム拡張子を設定します。 'odps.external.data.output.explicit.extension'='jsonl') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルのプレフィックスを
mc_に、サフィックスを_beijingに、拡張子をjsonlに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムプレフィックスを設定します。 'odps.external.data.output.prefix'='mc_', -- カスタムサフィックスを設定します。 'odps.external.data.output.suffix'='_beijing', -- カスタム拡張子を設定します。 'odps.external.data.output.explicit.extension'='jsonl') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。
