

 Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、[ブログ記事](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)を参照してください。

# Redshift Spectrum 用の外部テーブル
<a name="c-spectrum-external-tables"></a>

このトピックでは、Redshift Spectrum で外部テーブルの作成および使用する方法について説明します。外部テーブルは、Amazon Redshift クラスター外のデータにアクセスするための参照として使用するテーブルです。これらのテーブルには、Redshift Spectrum が読み取る外部データに関するメタデータが含まれています。



外部テーブルは外部スキーマで作成します。外部テーブルを作成するには、外部スキーマの所有者またはスーパーユーザーである必要があります。外部スキーマの所有者を移行するには、「[ALTER SCHEMA](r_ALTER_SCHEMA.md)」を使用して所有者を変更します。次の例は、`spectrum_schema`スキーマの所有者を `newowner` に変更します。

```
alter schema spectrum_schema owner to newowner;
```

Redshift Spectrum クエリを実行するには、次のアクセス権限が必要です。
+ スキーマのアクセス権限の使用 
+ 現在のデータベースに一時テーブルを作成するアクセス権限 

次の例では、スキーマ `spectrum_schema` の使用許可を `spectrumusers` ユーザーグループに付与しています。

```
grant usage on schema spectrum_schema to group spectrumusers;
```

次の例では、データベース `spectrumdb` の一時アクセス権限を `spectrumusers` ユーザーグループに付与しています。

```
grant temp on database spectrumdb to group spectrumusers;
```

外部テーブルは、Amazon Redshift、AWS Glue、Amazon Athena、または Apache Hive メタストア内に作成できます。詳細については、*AWS Glueデベロッパーガイド*の「[AWS Glue の使用開始](https://docs.aws.amazon.com/glue/latest/dg/getting-started.html)」、*Amazon Athena ユーザーガイド*の「[使用開始](https://docs.aws.amazon.com/athena/latest/ug/getting-started.html)」、または *Amazon EMR デベロッパーガイド*の「[Apache Hive](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive.html)」を参照してください。

外部テーブルが 、AWS Glue、Athena、または Hive メタストアで定義されている場合は、最初に外部データベースを参照する外部スキーマを作成します。その後、テーブル名の先頭にスキーマ名を付けることで、Amazon Redshift にテーブルを作成することなしに SELECT ステートメント内の外部テーブルを参照できます。詳細については、「[Amazon Redshift Spectrum 用の外部スキーマ](c-spectrum-external-schemas.md)」を参照してください。

Amazon Redshift で AWS Glue Data Catalog のテーブルを表示できるようにするには、Amazon Redshift IAM ロールに `glue:GetTable` を追加します。それ以外の場合は、以下のようなエラーが発生する場合があります。

```
RedshiftIamRoleSession is not authorized to perform: glue:GetTable on resource: *;
```

例えば、Athena 外部カタログに `lineitem_athena` という名前の外部テーブルが定義されているとします。この場合、`athena_schema`という名前の外部スキーマを定義し、次の SELECT ステートメントを使ってテーブルにクエリを実行できます。

```
select count(*) from athena_schema.lineitem_athena;
```

Amazon Redshift で外部テーブルを定義するには、[CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md) コマンドを使用します。外部テーブルステートメントはテーブル列、データファイルの型式、Amazon S3 内でのデータの場所を定義します。Redshift Spectrum は、指定されたフォルダおよびサブフォルダ内のファイルをスキャンします。Redshift Spectrum は、隠しファイル、ファイル名がピリオド、下線、ハッシュマーク (「.」、「\$1」、「\$1」) で始まるファイル、またはファイル名がチルド (「\$1」) で終わるファイルは無視します。

次の例では、SALES という名前のテーブルを `spectrum` という名前の Amazon Redshift 外部スキーマに作成します。データはタブ区切りのテキストファイルになっています。

```
create external table spectrum.sales(
salesid integer,
listid integer,
sellerid integer,
buyerid integer,
eventid integer,
dateid smallint,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp)
row format delimited
fields terminated by '\t'
stored as textfile
location 's3://redshift-downloads/tickit/spectrum/sales/'
table properties ('numRows'='172000');
```

外部テーブルを表示するには、[SVV\$1EXTERNAL\$1TABLES](r_SVV_EXTERNAL_TABLES.md)システムビューに対してクエリを実行します。

## 疑似列
<a name="c-spectrum-external-tables-pseudocolumns"></a>

デフォルトでは、Amazon Redshift は疑似列 (`$path`、`$size` および `$spectrum_oid`) を使用して外部テーブルを作成します。`$path` 列を選択すると、Amazon S3 のデータファイルへのパスが表示され、`$size` 列を選択するとクエリによって返された各行のデータファイルのサイズが表示されます。`$spectrum_oid` 列は、Redshift Spectrum で相関クエリを実行する機能を提供します。例については、[例: Redshift Spectrum での相関サブクエリの実行](c_performing-correlated-subqueries-spectrum.md)を参照してください。列名 (`$path`、`$size` および `$spectrum_oid`) は、二重引用符で囲う必要があります。SELECT \$1 句は、疑似列を返しません。次の例に示すように、`$path`、`$size`および `$spectrum_oid` の列名をクエリに明示的に含める必要があります。

```
select "$path", "$size", "$spectrum_oid"
from spectrum.sales_part where saledate = '2008-12-01';
```

セッションの疑似列の作成を無効にするには、`spectrum_enable_pseudo_columns`設定パラメータを `false` に設定します。詳細については、「[spectrum\$1enable\$1pseudo\$1columns](r_spectrum_enable_pseudo_columns.md)」を参照してください。`enable_spectrum_oid` を `false` に設定して、`$spectrum_oid`擬似列のみを無効にすることもできます。詳細については、「[enable\$1spectrum\$1oid](r_spectrum_enable_spectrum_oid.md)」を参照してください。ただし、`$spectrum_oid`疑似列 を無効にすると、Redshift Spectrum での相関クエリのサポートも無効になります。

**重要**  
Redshift Spectrum では、Amazon S3 のデータファイルをスキャンして結果セットのサイズを確認しているため、`$size`、`$path` または `$spectrum_oid` を選択すると料金が発生します。詳細については、[Amazon Redshift の料金](https://aws.amazon.com/redshift/pricing/)を参照してください。

### 疑似列の例
<a name="c-spectrum-external-tables-pseudocolumns-example"></a>

次の例では、外部テーブルの関連データファイルの合計サイズを返します。

```
select distinct "$path", "$size"
from spectrum.sales_part;

 $path                                                                    | $size
--------------------------------------------------------------------------+-------
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/ |  1616
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02/ |  1444
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03/ |  1644
```

## Redshift Spectrum 外部テーブルのパーティション化
<a name="c-spectrum-external-tables-partitioning"></a>

データをパーティション化する際は、パーティションキーをフィルタリングすることで Redshift Spectrum がスキャンするデータ量を制限できます。すべてのキーでデータをパーティション化できます。

一般的な方法では、時間に基づいてデータをパーティション化します。例えば、年、月、日、時ごとにパーティション化を行います。ソースのデータが多岐にわたる場合は、データソース ID と日付ごとにパーティション化できます。

次の手順でデータをパーティション化する方法を示します。

**データをパーティション化するには**

1. パーティションキーに従って Amazon S3 のフォルダにデータを保存します。

   パーティション値ごとにフォルダを 1 つ作成し、パーティションキーとパーティション値を使ってフォルダ名を設定します。例えば日付でパーティション化する場合、フォルダ名は [`saledate=2017-04-01`] や [`saledate=2017-04-02`] になります。Redshift Spectrum は、パーティションフォルダおよびサブフォルダ内のファイルをスキャンします。Redshift Spectrum は、隠しファイル、ファイル名がピリオド、下線、ハッシュマーク (「.」、「\$1」、「\$1」) で始まるファイル、またはファイル名がチルド (「\$1」) で終わるファイルは無視します。

1. 外部テーブルを作成し、PARTITIONED BY 句でパーティションキーを指定します。

   パーティションキーをテーブル列の名前と同じにすることはできません。SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、DOUBLE PRECISION、BOOLEAN、CHAR、VARCHAR、DATE、または TIMESTAMP データ型を使用できます。

1. パーティションを追加します。

   [ALTER TABLE](r_ALTER_TABLE.md) … ADD PARTITION を使用して各パーティションを追加し、パーティション列とキーバリュー、Amazon S3 内のパーティションフォルダの場所を指定します。単一の ALTER TABLE … ADD ステートメントを使用して複数のパーティションを追加できます。次の例では、`'2008-01'`と `'2008-03'` のパーティションを追加します。

   ```
   alter table spectrum.sales_part add
   partition(saledate='2008-01-01') 
   location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/'
   partition(saledate='2008-03-01') 
   location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03/';
   ```
**注記**  
AWS Glue を使用する場合、単一の ALTER TABLE ステートメントを使用して、最大 100 パーティションまで追加できます。

### データのパーティション化の例
<a name="c-spectrum-external-tables-partitioning-example"></a>

次の例では、1 つのパーティションキーでパーティション化された外部テーブルと、2 つのパーティションキーでパーティション化された外部テーブルを作成します。

この例のサンプルデータは、認証済みのすべての AWS ユーザーに読み取りアクセスを許可する Amazon S3 バケットに格納されています。クラスターと外部データファイルは、同じ AWS リージョン 存在する必要があります。サンプルデータバケットは、米国東部 (バージニア北部) リージョン (us-east-1) にあります。Redshift Spectrum を使用してデータにアクセスするには、クラスターも us-east-1 に存在する必要があります。Amazon S3 内のフォルダをリスト表示するには次のコマンドを実行します。

```
aws s3 ls s3://redshift-downloads/tickit/spectrum/sales_partition/
```

```
PRE saledate=2008-01/
PRE saledate=2008-03/
PRE saledate=2008-04/
PRE saledate=2008-05/
PRE saledate=2008-06/
PRE saledate=2008-12/
```

外部スキーマがない場合は、次のコマンドを実行します。AWS Identity and Access Management (IAM) ロールを Amazon リソースネーム (ARN) に置き換えます。

```
create external schema spectrum
from data catalog
database 'spectrumdb'
iam_role 'arn:aws:iam::123456789012:role/myspectrumrole'
create external database if not exists;
```

#### 例 1: 1 つのパーティションキーによるパーティション化
<a name="c-spectrum-external-tables-single-partition-example"></a>

次の例では、月別にパーティション化された外部テーブルを作成します。

月別にパーティション化された外部テーブルを作成するには、次のコマンドを実行します。

```
create external table spectrum.sales_part(
salesid integer,
listid integer,
sellerid integer,
buyerid integer,
eventid integer,
dateid smallint,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp)
partitioned by (saledate char(10))
row format delimited
fields terminated by '|'
stored as textfile
location 's3://redshift-downloads/tickit/spectrum/sales_partition/'
table properties ('numRows'='172000');
```

パーティションを追加するには、次の ALTER TABLE コマンドを実行します。

```
alter table spectrum.sales_part add
partition(saledate='2008-01') 
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/'

partition(saledate='2008-03') 
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03/'

partition(saledate='2008-04') 
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-04/';
```

パーティション化されたテーブルからデータを選択するには、次のクエリを実行します。

```
select top 5 spectrum.sales_part.eventid, sum(spectrum.sales_part.pricepaid) 
from spectrum.sales_part, event
where spectrum.sales_part.eventid = event.eventid
  and spectrum.sales_part.pricepaid > 30
  and saledate = '2008-01'
group by spectrum.sales_part.eventid
order by 2 desc;
```

```
eventid | sum     
--------+---------
   4124 | 21179.00
   1924 | 20569.00
   2294 | 18830.00
   2260 | 17669.00
   6032 | 17265.00
```

外部テーブルパーティションを表示するには、[SVV\$1EXTERNAL\$1PARTITIONS](r_SVV_EXTERNAL_PARTITIONS.md)システムビューにクエリを実行します。

```
select schemaname, tablename, values, location from svv_external_partitions
where tablename = 'sales_part';
```

```
schemaname | tablename  | values      | location                                                                
-----------+------------+-------------+-------------------------------------------------------------------------
spectrum   | sales_part | ["2008-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01
spectrum   | sales_part | ["2008-03"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03
spectrum   | sales_part | ["2008-04"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-04
```

#### 例 2: 複数のパーティションキーによるパーティション化
<a name="c-spectrum-external-tables-multi-partition-example"></a>

`date` と `eventid` でパーティション化された外部テーブルを作成するには、次のコマンドを実行します。

```
create external table spectrum.sales_event(
salesid integer,
listid integer,
sellerid integer,
buyerid integer,
eventid integer,
dateid smallint,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp)
partitioned by (salesmonth char(10), event integer)
row format delimited
fields terminated by '|'
stored as textfile
location 's3://redshift-downloads/tickit/spectrum/salesevent/'
table properties ('numRows'='172000');
```

パーティションを追加するには、次の ALTER TABLE コマンドを実行します。

```
alter table spectrum.sales_event add
partition(salesmonth='2008-01', event='101') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-01/event=101/'

partition(salesmonth='2008-01', event='102') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-01/event=102/'

partition(salesmonth='2008-01', event='103') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-01/event=103/'

partition(salesmonth='2008-02', event='101') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-02/event=101/'

partition(salesmonth='2008-02', event='102') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-02/event=102/'

partition(salesmonth='2008-02', event='103') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-02/event=103/'

partition(salesmonth='2008-03', event='101') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-03/event=101/'

partition(salesmonth='2008-03', event='102') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-03/event=102/'

partition(salesmonth='2008-03', event='103') 
location 's3://redshift-downloads/tickit/spectrum/salesevent/salesmonth=2008-03/event=103/';
```

次のクエリを実行するには、パーティション化されたテーブルからデータを選択します。

```
select spectrum.sales_event.salesmonth, event.eventname, sum(spectrum.sales_event.pricepaid) 
from spectrum.sales_event, event
where spectrum.sales_event.eventid = event.eventid
  and salesmonth = '2008-02'
	and (event = '101'
	or event = '102'
	or event = '103')
group by event.eventname, spectrum.sales_event.salesmonth
order by 3 desc;
```

```
salesmonth | eventname       | sum    
-----------+-----------------+--------
2008-02    | The Magic Flute | 5062.00
2008-02    | La Sonnambula   | 3498.00
2008-02    | Die Walkure     |  534.00
```

## 外部テーブル列を ORC 列にマッピングする
<a name="c-spectrum-column-mapping-orc"></a>

Amazon Redshift Spectrum 外部テーブルを使用して、ORC 形式のファイルからデータをクエリします。最適化された行列 (ORC) 形式は、ネストデータ構造をサポートする列指向ストレージファイル形式です。ネストデータをクエリする方法の詳細については、[Amazon Redshift Spectrum を使用したネストデータのクエリ](tutorial-query-nested-data.md#tutorial-nested-data-overview)を参照してください。

ORC ファイルのデータを参照する外部テーブルを作成する場合、外部テーブルの各列を ORC データにある列にマッピングします。それを行うには、次のいずれかの方法を使用します。
+ [位置によるマッピング](#orc-mapping-by-position)
+ [列名によるマッピング](#orc-mapping-by-name) 

列名によるマッピングがデフォルトです。

### 位置によるマッピング
<a name="orc-mapping-by-position"></a>

位置マッピングでは、外部テーブルで統合された最初の列は ORC データファイルの最初の列にマッピングし、2 番目は 2 番目に、のようになります。位置によるマッピングでは、外部テーブルと ORC ファイルの列の順序が一致する必要があります。列の順序が一致しない場合、名前で列をマッピングすることができます。

**重要**  
以前のリリースでは、Redshift Spectrum は位置によるマッピングをデフォルトで使用しました。既存のテーブルに引き続き位置マッピングを使用する必要がある場合は、次の例に示すように、テーブルプロパティ `orc.schema.resolution` を `position` に設定します。  

```
alter table spectrum.orc_example 
set table properties('orc.schema.resolution'='position');
```

例えば、テーブル `SPECTRUM.ORC_EXAMPLE` は次のように定義されています。

```
create external table spectrum.orc_example(
int_col int,
float_col float,
nested_col struct<
  "int_col" : int,
  "map_col" : map<int, array<float >>
   >
) stored as orc
location 's3://example/orc/files/';
```

テーブル構造は次のように抽象化することができます。

```
• 'int_col' : int
• 'float_col' : float
• 'nested_col' : struct
   o 'int_col' : int
   o 'map_col' : map
      - key : int
      - value : array
         - value : float
```

基盤となる ORC ファイルには次の構造があります。

```
• ORC file root(id = 0)
   o 'int_col' : int (id = 1)
   o 'float_col' : float (id = 2)
   o 'nested_col' : struct (id = 3)
      - 'int_col' : int (id = 4)
      - 'map_col' : map (id = 5)
         - key : int (id = 6)
         - value : array (id = 7)
            - value : float (id = 8)
```

この例では、外部テーブルの各列を ORC ファイルにある列に厳密に位置によってマッピングできます。以下にマッピングを示します。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-spectrum-external-tables.html)

### 列名によるマッピング
<a name="orc-mapping-by-name"></a>

名前マッピングを使用して、外部テーブルの列を同じレベル、同じ名前で ORC ファイルの名前を付けられた列にマッピングします。

たとえば、前の例、`SPECTRUM.ORC_EXAMPLE`のテーブルを次のファイル構造を使用する ORC ファイルにマッピングするとします。

```
• ORC file root(id = 0)
   o 'nested_col' : struct (id = 1)
      - 'map_col' : map (id = 2)
         - key : int (id = 3)
         - value : array (id = 4)
            - value : float (id = 5)
      - 'int_col' : int (id = 6)
   o 'int_col' : int (id = 7)
   o 'float_col' : float (id = 8)
```

位置マッピングを使用して、Redshift Spectrum は以下のマッピングを試行します。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-spectrum-external-tables.html)

前述の位置マッピングでテーブルに対してクエリを実行すると、構造が異なるため SELECT コマンドはタイプ検証で失敗します。

列名マッピングを使用して、同じ外部テーブルを前の例に示されている両方のファイル構造にマッピングできます。テーブル列 `int_col`、`float_col`、`nested_col`は、ORC ファイルにある同じ名前の列に列名でマッピングします。外部テーブルにある `nested_col` という名前の列は、`map_col`と `int_col` という名前のサブ列がある `struct` 列です。サブ列も列名で ORC ファイルにある対応する列に正しくマッピングします。

## Apache Hudi で管理されるデータの外部テーブルの作成
<a name="c-spectrum-column-mapping-hudi"></a>

Apache Hudi 書き込みコピー (CoW) 形式のデータをクエリするには、Amazon Redshift Spectrum の外部テーブルを使用できます。Hudi Copy On Write テーブルは、Amazon S3 に保存されている Apache Parquet ファイルのコレクションです。Apache Hudi バージョン 0.5.2、0.6.0、0.7.0、0.8.0、0.9.0、0.10.0、0.10.1、0.11.0、0.11.1 で、挿入、削除、アップサート書き込みオペレーションによって作成および変更された、Copy On Write (CoW) テーブルを読み取ることができます。例えば、ブートストラップテーブルはサポートされていません。詳細については、オープンソースの Apache Hudi ドキュメントから[書き込みテーブルでコピー](https://hudi.apache.org/docs/next/table_types#copy-on-write-table)を参照してください。

Hudi CoW 形式のデータを参照する外部テーブルを作成する場合、外部テーブルの各列を Hudi データにある列にマッピングします。マッピングは列ごとに行われます。

パーティション分割された Hudi テーブルおよびパーティション分割されていない Hudi テーブルのデータ定義言語 (DDL) ステートメントは、他の Apache Parquet ファイル形式のステートメントと似ています。Hudi テーブルの場合、`INPUTFORMAT` を `org.apache.hudi.hadoop.HoodieParquetInputFormat` として定義します。`LOCATION` パラメータは、`.hoodie` フォルダを含む Hudi テーブルベースフォルダを指している必要があります。これは、Hudi コミットタイムラインを確立するために必要です。場合によっては、Hudi テーブルに対する SELECT オペレーションが失敗し、有効な Hudi コミットのタイムラインが見つかりませんというメッセージが表示されることがあります。その場合は、`.hoodie`フォルダが正しい場所にあり、有効な Hudi コミットのタイムラインが含まれているかどうかを確認してください。

**注記**  
Apache Hudi 形式は、AWS Glue Data Catalogを使用する場合にのみサポートされます。Apache Hive メタストアを外部カタログとして使用する場合は、サポートされません。

パーティション分割されていないテーブルを定義する DDL の形式を次に示します。

```
CREATE EXTERNAL TABLE tbl_name (columns)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://s3-bucket/prefix'
```

パーティション分割されたテーブルを定義する DDL の形式を次に示します。

```
CREATE EXTERNAL TABLE tbl_name (columns)
PARTITIONED BY(pcolumn1 pcolumn1-type[,...])
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://s3-bucket/prefix'
```

パーティション分割された Hudi テーブルにパーティションを追加するには、ALTER TABLE ADD PARTITION コマンドを実行します。ここで、`LOCATION` パラメータは、パーティションに属するファイルを含む Amazon S3 サブフォルダを指します。

パーティションを追加する DDL の形式を以下に示します。

```
ALTER TABLE tbl_name
ADD IF NOT EXISTS PARTITION(pcolumn1=pvalue1[,...])
LOCATION 's3://s3-bucket/prefix/partition-path'
```

## Delta Lake で管理されるデータの外部テーブルの作成
<a name="c-spectrum-column-mapping-delta"></a>

Delta Lake テーブルのデータをクエリするには、Amazon Redshift Spectrum 外部テーブルを使用できます。

Redshift Spectrum から Delta Lake テーブルにアクセスするには、クエリの前にマニフェストを生成します。Delta Lake *マニフェスト*には、Delta Lake テーブルの一貫したスナップショットを構成するファイルのリストが含まれています。パーティション化されたテーブルには、パーティションごとに 1 つのマニフェストがあります。Delta Lake テーブルは、Amazon S3 に保存されている Apache Parquet ファイルのコレクションです。詳細については、オープンソースの Delta Lake のドキュメントから [Delta Lake](https://delta.io) を参照してください。

Delta Lake テーブルのデータを参照する外部テーブルを作成する場合、外部テーブルの各列を Delta Lake テーブルにある列にマッピングします。マッピングは列名ごとに行われます。

パーティション分割された、パーティション分割されていない Delta Lake テーブルの DDL は、他の Apache Parquet ファイル形式の場合と同様です。Delta Lake テーブルの場合、`INPUTFORMAT` を `org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat` として、`OUTPUTFORMAT` を `org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat` として定義します。`LOCATION` パラメータは、テーブルベースフォルダ内のマニフェストフォルダを指している必要があります。Delta Lake テーブルに対する SELECT オペレーションが失敗した場合、考えられる理由については「[Delta Lake テーブルの制限事項とトラブルシューティング](#c-spectrum-column-mapping-delta-limitations)」を参照してください。

パーティション分割されていないテーブルを定義する DDL の形式を次に示します。

```
CREATE EXTERNAL TABLE tbl_name (columns)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://s3-bucket/prefix/_symlink_format_manifest'
```

パーティション分割されたテーブルを定義する DDL の形式を次に示します。

```
CREATE EXTERNAL TABLE tbl_name (columns)
PARTITIONED BY(pcolumn1 pcolumn1-type[,...])
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://s3-bucket>/prefix/_symlink_format_manifest'
```

パーティション化された Delta Lake テーブルにパーティションを追加するには、ALTER TABLE ADD PARTITION コマンドを実行します。ここで、`LOCATION` パラメータは、パーティションのマニフェストを含む Amazon S3 サブフォルダを指します。

パーティションを追加する DDL の形式を以下に示します。

```
ALTER TABLE tbl_name
ADD IF NOT EXISTS PARTITION(pcolumn1=pvalue1[,...])
LOCATION
's3://s3-bucket/prefix/_symlink_format_manifest/partition-path'
```

または、Delta Lake マニフェストファイルを直接指す DDL を実行します。

```
ALTER TABLE tbl_name
ADD IF NOT EXISTS PARTITION(pcolumn1=pvalue1[,...])
LOCATION
's3://s3-bucket/prefix/_symlink_format_manifest/partition-path/manifest'
```

### Delta Lake テーブルの制限事項とトラブルシューティング
<a name="c-spectrum-column-mapping-delta-limitations"></a>

Redshift Spectrum から Delta Lake テーブルをクエリする場合は、次の点を考慮してください。
+ マニフェストが存在しなくなったスナップショットまたはパーティションを指している場合、新しい有効なマニフェストが生成されるまでクエリは失敗します。例えば、これは、基になるテーブルに対する VACUUM オペレーションの結果である可能性があります。
+ Delta Lake マニフェストは、パーティションレベルの整合性のみを提供します。

次のテーブルでは、Delta Lake テーブルをクエリするときに特定のエラーが発生する可能性のある理由について説明します。


| エラーメッセージ | 考えられる理由 | 
| --- | --- | 
| バケット*s3-bucket-1* の Delta Lake マニフェストに、バケット* s3-bucket-2* のエントリを含めることはできません。 | マニフェストエントリは、指定されたバケットとは異なる Amazon S3 バケット内のファイルを指しています。 | 
| Delta Lake ファイルは、同じフォルダにあると予想されます。 | マニフェストエントリは、指定されたものとは異なる Amazon S3 プレフィックスを持つファイルを指します。 | 
| Delta Lake マニフェストの*マニフェストパス*に表示されるファイルの*ファイル名*が見つかりませんでした。 | マニフェストに表示されているファイルが Amazon S3 で見つかりませんでした。 | 
| Delta Lake マニフェストの取得中にエラーが発生しました。 | マニフェストは Amazon S3 では見つかりませんでした。 | 
| 無効な S3 パスです。 | マニフェストファイルのエントリが有効な Amazon S3 パスではないか、マニフェストファイルが破損しています。 | 