Amazon Web Services ブログ
DuckDB で Amazon S3 Tables に格納された表形式データセットへのアクセスを効率化する
本記事は 2025 年 3 月 18 日 に公開された「Streamlining access to tabular datasets stored in Amazon S3 Tables with DuckDB」を翻訳したものです。
データドリブンな意思決定への依存が高まるなか、データ分析のプロセスを効率化・高速化するツールへの需要が増しています。重要な意思決定を進める場面では、アプリケーションアーキテクチャの効率性とシンプルさが競争優位につながります。開発者は、既存のアプリケーションスタックとスムーズに統合できる軽量で柔軟なツールを求めています。特に、データレイクに保存されたデータセットを素早く効率的にクエリするための手段が重視されています。
こうした状況において、DuckDB は複雑なインストールなしにデータを素早く分析できる実用的な選択肢として注目されています。DuckDB はホストプロセスに完全に組み込まれ、別プロセスとして動作しないため、インストール・更新・保守が必要な別サーバーやソフトウェアを用意する必要がありません。軽量な設計により、Python、Java、その他の環境に容易に統合でき、対話型のデータ分析に適しています。DuckDB には最近、Apache Iceberg REST API を利用して Amazon S3 Tables に格納されたテーブルを読み取るプレビューサポートが追加されました。S3 Tables は表形式ストレージ専用に設計されており、Apache Iceberg 形式のデータを直接、高性能かつ低コストで保存・クエリできます。S3 Tables はストレージを継続的に最適化してクエリ性能を最大化し、コストを最小化するため、追加のインフラ構築なしにデータレイク運用を効率化したい企業に適しています。DuckDB と S3 Tables の統合により、開発者は Amazon S3 に格納されたデータをクエリでき、複雑なデータ移動や追加のインフラなしにテーブルへアクセスしながら、企業はデータレイクを効率化・集約できます。
本記事では、Amazon SageMaker Lakehouse Iceberg REST エンドポイントと AWS Lake Formation のアクセス許可を利用して、ローカルマシンから DuckDB で S3 テーブルバケット内の Iceberg テーブルを読み取る方法を紹介します。同じデータ利用ワークフローは、リソースが限られた小型のエッジデバイスから、100 コア超の CPU を搭載する数テラバイトメモリの大型サーバーまで、幅広い環境で適用できます。DuckDB と S3 Tables の組み合わせは、AWS 上でスケーラブルなデータレイク構築を始めるための、直接的で堅牢な基盤になります。
ソリューションの概要
本記事では、AWS CloudShell の CLI で DuckDB を使い、ローカルシステムから S3 バケットのテーブルを読み取る方法を紹介します。ここではコマンドラインインターフェイスを使いますが、DuckDB は複数のプログラミング言語とクライアント API をサポートしています。対応言語と統合オプションの一覧は、DuckDB 公式ドキュメントを参照してください。また、本記事では、開発者やデータサイエンティストがローカル環境でクエリをテスト・反復してから本番規模でデプロイするという、一般的なパターンを扱います。まずクライアントに DuckDB をインストールし、次の図のように S3 テーブルバケットに格納されたテーブルへアクセスするための Lake Formation のアクセス許可を接続します。その後、クライアント上の DuckDB インスタンスにカタログをアタッチし、テーブルに対するクエリを試します。

前提条件
本記事の手順を実行するには、次の AWS サービスにアクセスできる AWS アカウントが必要です。
- Amazon S3 Tables
- AWS Identity and Access Management (IAM)
- Amazon SageMaker Lakehouse
- Amazon Athena
- AWS Lake Formation
ウォークスルー
本ソリューションを実装するには、S3 テーブルバケットにテーブルを用意し、テーブルを読み取るためのアクセス許可を設定し、ローカルクライアントに DuckDB インスタンスを構成する必要があります。以降のセクションで各ステップを説明します。
- Part A: S3 Tables のセットアップ
- Part B: アクセス許可のセットアップ (オプション)
- Part C: DuckDB のセットアップ
Part A: S3 Tables のセットアップ
DuckDB は現時点で S3 Tables を読み取り専用モードでサポートしています。アカウントにテーブルがない、または AWS 分析サービスとの統合が未設定の場合は、以下の手順に従ってください。すでに設定済みであれば、本セクションはスキップできます。本セクションでは、テーブルバケットの作成、テーブルのセットアップ、データ追加を通じて、DuckDB で分析するためのデータを準備する手順を説明します。すでにデータが入ったテーブルがある場合は、本セクションをスキップして次のセクションに進んでください。
1. S3 テーブルバケットを作成し、AWS 分析サービスとの統合をセットアップする
1.1. AWS マネジメントコンソールで S3 に移動します。左のナビゲーションメニューから Table buckets を選択し、Create table bucket を選びます。テーブルバケット名を指定し、次の図のように AWS 分析サービスとの統合が未有効の場合は Enable integration を選択します。この統合により、この AWS リージョンとこのアカウントで作成されたすべてのテーブルを SageMaker Lakehouse と Lake Formation で検出でき、Amazon Data Firehose、Athena、Amazon Redshift、Amazon EMR などの AWS 分析サービスからアクセスできるようになります。統合の詳細は、Using Amazon S3 with analytics services を参照してください。

1.2. テーブルバケット mytraveldata が作成されました。DuckDB のセットアップで後ほど使うため、コピーアイコンでテーブルバケットの Amazon リソースネーム (ARN) をコピーしておきます。

2. テーブルバケットに新しいテーブルを作成する
2.1. S3 コンソールで対象のバケットに移動し、Create table with Athena を選択します。

2.2. テーブルバケット内に名前空間とテーブルを作成する
Create table ワークフローで Namespace name を追加します。

続けて Create table with Athena に進みます。

SageMaker Lakehouse に nyc という名前のデータベースが作成されます。
2.3. Athena クエリエディタで、次の SQL コマンドを使ってテーブルを作成します。
CREATE TABLE nyc.nyc_trips (trip_id INT,
pickup_datetime TIMESTAMP,
dropoff_datetime TIMESTAMP,
passenger_count INT,
trip_distance DOUBLE,
fare_amount DOUBLE,
payment_type STRING,
pickup_zone STRING) TBLPROPERTIES ( 'table_type'='ICEBERG' );
3. S3 Tables にデータを挿入する
ここでは、次の SQL コマンドを使い、ニューヨーク市のタクシー走行に関するサンプルデータを、作成済みのテーブルに挿入します。
INSERT INTO nyc.nyc_trips (trip_id, pickup_datetime, dropoff_datetime, passenger_count, trip_distance, fare_amount, payment_type, pickup_zone)
VALUES
(1, TIMESTAMP '2023-03-01 08:30:00', TIMESTAMP '2023-03-01 09:15:00', 2, 5.8, 22.50, 'Credit Card', 'Midtown'),
(2, TIMESTAMP '2023-03-01 12:15:00', TIMESTAMP '2023-03-01 12:45:00', 1, 3.2, 15.00, 'Cash', 'Upper East Side'),
(3, TIMESTAMP '2023-03-01 17:00:00', TIMESTAMP '2023-03-01 17:45:00', 3, 7.1, 28.75, 'Credit Card', 'Financial District'),
(4, TIMESTAMP '2023-03-02 09:45:00', TIMESTAMP '2023-03-02 10:30:00', 1, 4.5, 18.25, 'Credit Card', 'Chelsea'),
(5, TIMESTAMP '2023-03-02 14:30:00', TIMESTAMP '2023-03-02 15:15:00', 2, 6.3, 24.50, 'Cash', 'Greenwich Village'),
(6, TIMESTAMP '2023-03-02 20:00:00', TIMESTAMP '2023-03-02 20:30:00', 4, 2.8, 14.75, 'Credit Card', 'Times Square'),
(7, TIMESTAMP '2023-03-03 07:15:00', TIMESTAMP '2023-03-03 08:00:00', 1, 8.2, 32.00, 'Credit Card', 'Brooklyn Heights'),
(8, TIMESTAMP '2023-03-03 11:30:00', TIMESTAMP '2023-03-03 12:15:00', 2, 5.5, 21.75, 'Cash', 'East Village'),
(9, TIMESTAMP '2023-03-03 16:45:00', TIMESTAMP '2023-03-03 17:30:00', 3, 6.7, 26.25, 'Credit Card', 'SoHo'),
(10, TIMESTAMP '2023-03-03 22:00:00', TIMESTAMP '2023-03-03 22:45:00', 1, 4.9, 19.50, 'Cash', 'Upper West Side');
この SQL コマンドを実行すると、データが nyc_trips テーブルに取り込まれます。

Part B: アクセス許可のセットアップ (オプション)
当該アカウントで AWS 分析サービスとテーブルバケットの統合を行ったユーザーとは別のユーザーの場合、テーブルに対する Lake Formation のアクセス許可を付与してもらう必要があります。詳細は Grant permission on a table or database を参照してください。本記事では、コンソール上で AWS 分析サービスとの統合を行った同じユーザーが、DuckDB インスタンス経由でテーブルにアクセスすることを前提とします。
Part C: DuckDB のセットアップ
1. DuckDB をインストールする
DuckDB のインストールページにアクセスし、最新の DuckDB Command line (執筆時点は v1.2.1) を入手します。Installation セクションの curl コマンドをコピーします。
AWS マネジメントコンソールで CloudShell 環境に移動します。

次の curl コマンドを実行します。
curl https://install.duckdb.org | sh
次の図は curl コマンドの実行例です。

2. CloudShell インスタンスで DuckDB インスタンスを実行する
DuckDB インスタンスを起動するには、AWS Command Line Interface (AWS CLI) で次のコマンドを入力します。
/home/cloudshell-user/.duckdb/cli/latest/duckdb

3. Iceberg 拡張機能をロードする
S3 Tables の DuckDB サポートは、現時点では nightly 拡張ビルドの一部として提供されています。最新の Iceberg 拡張機能をインストールするには、次のコマンドを実行します。
FORCE INSTALL iceberg FROM core_nightly;
ここまでで DuckDB インスタンスのセットアップは完了です。
4. AWS 認証情報を登録する
AWS 認証情報を含むシークレットを作成します。CloudShell を使用している場合、これは AWS コンソールの認証情報にあたります。DuckDB はこのシークレットを使ってテーブルデータにアクセスします。設定オプションの詳細は DuckDB のドキュメントを参照してください。
CREATE SECRET ( TYPE S3, PROVIDER credential_chain );
5. カタログをデータベースとしてアタッチする
ここでは、テーブルバケットをデータベースインスタンスとして DuckDB にアタッチします。
ATTACH '<account-id>:s3tablescatalog/mytraveldata' AS duck_db (TYPE ICEBERG, ENDPOINT_TYPE 'GLUE');
6. テーブルバケットに格納されたデータにアクセスする
次のコマンドを使い、DuckDB がテーブルバケット内のテーブルを検出できることを確認します。

SHOW ALL TABLES;
結果から、mytraveldata には nyc という名前空間が 1 つあり、その中に nyc_trips というテーブルが 1 つ存在することがわかります。以下はテーブルに格納されたデータを分析するサンプルクエリの例です。
6.1. テーブルに格納されたすべてのデータを表示します。
SELECT * from duck_db.nyc.nyc_trips

6.2. 支払い方法別の運賃合計を取得します。
SELECT payment_type, SUM(fare_amount) AS total_fare
FROM duck_db.nyc.nyc_trips
GROUP BY payment_type;

6.3. 2023 年 3 月 1 日の走行に対する運賃合計を取得します。
SELECT SUM(fare_amount) AS total_fare
FROM duck_db.nyc.nyc_trips
WHERE pickup_datetime BETWEEN '2023-03-01 00:00:00' AND '2023-03-01 23:59:59';

本記事では、DuckDB インスタンスへの接続に Amazon SageMaker Lakehouse Iceberg REST エンドポイントを利用しました。もう 1 つの選択肢として、S3 Tables Iceberg REST Catalog API で DuckDB に接続することもできます。この場合は、次の ATTACH コマンドを使用します。
ATTACH '<table-bucket-arn>' AS duck_db (TYPE ICEBERG, ENDPOINT_TYPE 'S3_Tables');
1 つの S3 テーブルバケット内の表形式データに基本的な読み取りアクセスが必要な場合は S3 Tables Iceberg REST Catalog API を使い、すべての表形式データを対象とした統一的なデータ管理、データガバナンス、きめ細かなアクセス制御が必要な場合は S3 Tables を SageMaker Lakehouse と組み合わせて利用できます。
クリーンアップ
リソースをクリーンアップするには、次の手順を実行してください。
まとめ
本記事では、Amazon SageMaker Lakehouse と AWS Lake Formation のアクセス許可を活用し、DuckDB で Amazon S3 上の Iceberg テーブルを読み取る方法を紹介しました。S3 テーブルバケットにテーブルを作成し、データを投入し、DuckDB クライアントからテーブルにアクセスする流れをウォークスルーしました。DuckDB と Amazon S3 Tables を組み合わせることで、小規模から大規模までのあらゆる環境で、追加のインフラなしにデータレイク内のテーブルを扱えます。
著者について
この記事は Kiro が翻訳を担当し、Solutions Architect の Sotaro Hikita がレビューしました。
