

# Hive に外部テーブルを作成します
<a name="EMRforDynamoDB.ExternalTableForDDB"></a>

[チュートリアル:Amazon DynamoDB と Apache Hive の使用](EMRforDynamoDB.Tutorial.md) において、DynamoDB テーブルにマッピングされた外部 Hive テーブルを作成しました。この状態で外部テーブルに対して HiveQL ステートメントを発行すると、読み込み/書き込みの操作が DynamoDB テーブルに渡されます。

外部テーブルは、他の場所で管理および格納されているデータソースへのポインタと捉えることができます。ここでは、基盤となるそのデータソースは、DynamoDB テーブルです。(このテーブルは外部に用意する必要があります。Hive 内から DynamoDB テーブルを作成、更新、または削除することはできません。) 外部テーブルの作成には、`CREATE EXTERNAL TABLE` ステートメントを使用します。その後は、DynamoDB 内のデータが Hive 内にローカルに格納されているかのように、HiveQL を使用してそのデータを操作できます。

**注記**  
`INSERT` ステートメントを使用すると、外部テーブルにデータを挿入でき、また、`SELECT` ステートメントにより、そのテーブルのデータを選択できます。ただし、テーブル内のデータを操作するために、`UPDATE` または `DELETE` ステートメントを使用することはできません。

外部テーブルが必要でなくなった時に、`DROP TABLE` を使ってそのテーブルを削除します。この場合でも、`DROP TABLE` は Hive の外部テーブルだけを削除します。このオペレーションは、基盤となっている DynamoDB テーブルまたはそのデータには影響を与えません。

**Topics**
+ [CREATE EXTERNAL TABLE 構文](#EMRforDynamoDB.ExternalTableForDDB.Syntax)
+ [データ型のマッピング](#EMRforDynamoDB.ExternalTableForDDB.DataTypes)

## CREATE EXTERNAL TABLE 構文
<a name="EMRforDynamoDB.ExternalTableForDDB.Syntax"></a>

DynamoDB テーブルにマッピングする外部 Hive テーブルを作成するための HiveQL 構文を次に示します。

```
CREATE EXTERNAL TABLE hive_table
    (hive_column1_name hive_column1_datatype, hive_column2_name hive_column2_datatype...)
STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
TBLPROPERTIES (
    "dynamodb.table.name" = "dynamodb_table",
    "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name..."
);
```

1 行目から `CREATE EXTERNAL TABLE` ステートメントが始まりますが、作成する Hive テーブルの名前 (hive\$1table) を指定します。

2 行目では、hive\$1table の列とデータ型を指定します。DynamoDB テーブルの属性に対応する列とデータ型を定義する必要があります。

3 行目は `STORED BY` 句で、ここでは、Hive と DynamoDB テーブル間のデータ管理を処理するクラスを指定します。DynamoDB の場合、`STORED BY` は `'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'` に設定する必要があります。

4 行目で `TBLPROPERTIES` 句が始まり、以下の `DynamoDBStorageHandler` のパラメータを定義しています。
+ `dynamodb.table.name` – DynamoDB テーブルの名前。
+  `dynamodb.column.mapping` – Hive テーブルの列名と DynamoDB テーブルの対応する属性のペア。各ペアの形式は、hive\$1column\$1name:dynamodb\$1attribute\$1name とし、それぞれをカンマで区切ります。

次の点に注意してください。
+ Hive テーブル名の名前は、DynamoDB テーブル名と同じである必要はありません。
+ Hive テーブルの列名は、DynamoDB テーブルの列名と同じである必要はありません。
+ `dynamodb.table.name` で指定されたテーブルは、DynamoDB 内に置いてある必要があります。
+ 複数 `dynamodb.column.mapping`:
  + DynamoDB テーブルには、キースキーマ属性をマッピングする必要があります。これには、パーティションキーと (それが存在する場合は) ソートキー が含まれます。
  + DynamoDB テーブルの非キー属性のマッピングは、必須ではありません。ただし、Hive テーブルに対しクエリを実行しても、マッピングしていないこれらの属性のデータは表示されません。
  + Hive テーブルの列のデータ型と DynamoDB 属性のデータ型に互換性がない場合、Hive テーブルをクエリすると、これらの列には `NULL` が表示されます。

**注記**  
`CREATE EXTERNAL TABLE` ステートメントでは、`TBLPROPERTIES` 句に関する検証は行われません。`dynamodb.table.name` および `dynamodb.column.mapping` に指定した値は、テーブルへのアクセスを試みた時点で、 クラスによってのみ評価されます。

## データ型のマッピング
<a name="EMRforDynamoDB.ExternalTableForDDB.DataTypes"></a>

次の表に、DynamoDB でのデータ型と、それに互換性のある Hive でのデータ型を示します。


****  

| DynamoDB データ型 | Hive データ型 | 
| --- | --- | 
|  文字列  |  `STRING`  | 
|  数値  |  `BIGINT`-または-`DOUBLE`  | 
|  バイナリ  |  `BINARY`  | 
|  文字列セット  |  `ARRAY<STRING>`  | 
|  数値セット  |  `ARRAY<BIGINT>` または `ARRAY<DOUBLE>`  | 
|  バイナリセット  |  `ARRAY<BINARY>`  | 

**注記**  
以下の DynamoDB データ型は、`DynamoDBStorageHandler` クラスではサポートされないため、`dynamodb.column.mapping` とともに使用することはできません。  
マップ
リスト
ブール値
Null
ただし、これらのデータ型を処理する必要がある場合は、DynamoDB アイテム全体を、マップ内のキーと値の両方の文字列のマップとして表す `item` という名前の 1 つのエンティティを作成できます。詳細については、[列マッピングを使用しないデータをコピー](EMRforDynamoDB.CopyingData.S3.md#EMRforDynamoDB.CopyingData.S3.NoColumnMapping)を参照してください。

数値型の DynamoDB 属性をマッピングする場合は、適切な Hive タイプを選択する必要があります。
+ Hive `BIGINT` 型は 8 バイトの符号付き整数です。これは、Java での `long` データ型と等価です。
+ Hive `DOUBLE` 型は 8 ビット倍精度浮動小数点数です。これは、Java での `double` 型と等価です。

選択した Hive データ型よりも精度が高い数値データが DynamoDB に格納されている場合、DynamoDB データにアクセスすると精度を損失する可能性があります。

DynamoDB から HDFS (または Amazon S3) にバイナリ型のデータをエクスポートすると、データは Base64 でエンコードされた文字列として格納されます。Amazon S3 または HDFS から DynamoDB に対し、バイナリ型でデータをインポートする場合には、そのデータが Base64 文字列としてエンコードされていることを確認します。