初級読了 4 分

DynamoDB のための SQL: 何が動き、何が動かず、そして Workbench

DynamoDB は NoSQL のキーバリューストアですが、人々が予想する以上に SQL 風の質問に 答え — そして期待するよりはるかに少なく答えます。これは正直な地図です。DynamoDB 上の SQL として実際に標準で得られるもの、それがどこで止まるのか、そしてネイティブの表層が 表現できない JOIN / GROUP BY / 集計クエリを実行する数少ない方法です。

DynamoDB を SQL でクエリできる? 短い答え

部分的に。DynamoDB は PartiQL を搭載しており、 AWS ドキュメントは これを「Amazon DynamoDB のデータを選択、挿入、更新、削除するための SQL 互換の クエリ言語」と説明しています。つまり SELECT * FROM "Orders" WHERE OrderID = 100 と 書けて、動きます。

しかし PartiQL は DynamoDB API の上にある SQL 互換の表層 であって、SQL エンジン ではありません。構文は話しますが、リレーショナルなクエリ能力を 追加しません。AWS は 「Amazon DynamoDB は PartiQL クエリ言語の サブセット をサポートする」と明言しています (リファレンス)。 JOINGROUP BYCOUNT(*) に手を伸ばした瞬間、PartiQL ができることの外側にいます — 機能ごとの完全な比較は PartiQL vs SQL を参照してください。

PartiQL: SQL 互換の表層であって SQL エンジンではない

PartiQL は SQL 風に見える文を、SDK が公開するのと同じデータプレーン操作にマッピング します。パーティションキーの等価性を持つ SELECTQuery にコンパイルされ、それが ない SELECTScan にコンパイルされます。 AWS の SELECT リファレンスより:

WHERE 句でパーティションキーとの等価条件または IN 条件が提供されない場合、SELECT 文はフルテーブルスキャンになり得ます。

つまり QueryScan を支配するのと同じアクセスパターンのルールが依然として適用 されます — PartiQL はそれらを見慣れた構文の裏に隠すだけです。クエリプランナーも、結合も、 集合ベースの集計も追加しません。すべての文は 1 つのネイティブ操作に畳み込まれます。

あなたが書くものDynamoDB が実行するもの
SELECT … WHERE PK = …GetItem または Query
SELECT …(PK なし)Scanテーブル全体 を読む)
INSERT INTO …PutItem
UPDATE … WHERE PK=… AND SK=…UpdateItem(1 アイテム)
DELETE … WHERE PK=… AND SK=…DeleteItem(1 アイテム)

操作が単一の Get/Query/Scan/Put/Update/Delete に還元されなければ、PartiQL はそれを 表現できません。以下のすべては、その 1 つの事実の帰結です。

PartiQL がカバーするもの

DynamoDB の PartiQL は 4 つの DML / クエリ文をサポートします。

  • SELECT — アイテムを読む(Query または Scan にコンパイル)
  • INSERT — アイテムを追加(PutItem
  • UPDATE — アイテムを変更(UpdateItem
  • DELETE — アイテムを削除(DeleteItem

また トランザクションとバッチ操作も サポートします。整形された読み取りは、等価性または IN でパーティションキーを対象に します。

SELECT OrderID, Total
FROM "Orders"
WHERE OrderID IN [1, 2, 3] ORDER BY OrderID DESC

ORDER BY は許可されますが、AWS リファレンスは順序付けキーを「ハッシュキーまたは ソートキー」 — パーティションキーまたはソートキーであり、任意の列ではない — に制限 します。それが PartiQL の SELECT が受け入れるものの天井です。コピペできる文については PartiQL の例を参照してください。

PartiQL にできないこと

これらは開発者が「SQL」に最もよく期待するもので、PartiQL はその どれも サポート しません。

  • JOIN なし。 PartiQL の SELECT 構文は 単一の FROM {{table}}[.{{index}}] です — 1 つのテーブルまたは 1 つのインデックスで あり、キーで関連付けた 2 つのテーブルではありません。これは シングルテーブル設計のトレードオフです。クエリ層が後で データを再形成できないので、アクセスパターンに合わせて事前にモデリングします。
  • GROUP BY なし。 文法にありません。行をグループ化する句はありません。
  • 集計関数なし。 PartiQL 関数リファレンスは 「集計関数」の下にちょうど 1 つの関数を挙げています: SIZE、これは 単一 アイテムの 属性のバイトサイズを返します。行をまたぐ COUNTSUMAVGMINMAX はありません。 AWS は端的に述べています: 「このリストに含まれない SQL 関数は、現在 DynamoDB では サポートされていない。」
  • LIKE なし、サブクエリなし、UNION なし、ウィンドウ関数なし。 パターンマッチングは contains / begins_with を使い、残りには同等のものがまったくありません。

そのため「先月の顧客ごとの総売上」 — どんなリレーショナルデータベースでも 1 行の GROUP BY — は PartiQL では表現できません。データをスキャンで取り出して、アプリケーション コードで集計することになります。

DynamoDB データに対して本物の JOIN / GROUP BY / 集計の振る舞いを得る唯一の方法は、 その上で 実際の SQL エンジン を実行するツールです。2 つあります: Amazon Athena の フェデレーテッドコネクタと、DynoTable の SQL Workbench です。

Amazon Athena 経由で DynamoDB を本物の SQL でクエリする方法

「DynamoDB 上の本物の SQL」への AWS 自身の答えは Amazon Athena DynamoDB コネクタで、 「Amazon Athena が DynamoDB と通信できるようにし、テーブルを SQL でクエリできるように する」ものです。Athena は完全な SQL エンジンなので、これは JOIN と集計を 実際に 得られます — AWS の手順は「Athena を使って Amazon DynamoDB テーブルにアクセス、 クエリ、結合する」と 題されています。

落とし穴はセットアップとコストです。

  • アカウントにデプロイする Lambda ベースのフェデレーテッドコネクタ です(Athena コンソールまたは Serverless Application Repository 経由)。スキーマには AWS Glue を 通して接続し、結果は S3 バケットにスピルします (コネクタドキュメント)。
  • 内部では依然として DynamoDB の QueryScan API 操作を使います。AWS は「スキャンを 使うクエリは大量の読み取りキャパシティユニット(RCU)を消費し得る」と警告しているので、 大きなテーブルに対する分析クエリは多くのアイテムを読み取り — そして課金します (コネクタのコスト)。 スキャンの多いクエリのコストを測るには アイテムサイズ計算機を使ってください。
  • INSERT INTO のような書き込み操作はコネクタ経由ではサポートされません。

Athena はスケジュールされた分析や BI ダッシュボードに適したツールです。「2 つのテーブルを 結合して結果を目で見たいだけ」という日常的なケースには重すぎます — それが次のセクションが 埋めるギャップです。

DynoTable SQL Workbench: DynamoDB のアクセスパターンのルール内での SQL

DynoTable の SQL Workbench は、Lambda、Glue、S3 を立ち上げることなく、デスクトップ クライアントからライブの DynamoDB テーブルに対して本物の SQL — JOINGROUP BYCOUNT/SUM/AVG — を実行します。DynamoDB の本物の Query/Scan ランタイムを通して 行をマテリアライズし、その上でインメモリエンジンで完全な SQL を実行します。

-- DynoTable Workbench で実行(PartiQL ではない):
SELECT c.country, COUNT(*) AS orders, SUM(o.total) AS revenue
FROM orders o
INNER JOIN customers c ON o.customerId = c.PK
GROUP BY c.country
ORDER BY revenue DESC

「DynamoDB のアクセスパターンのルール内で」という部分が重要です。Workbench は DynamoDB が Postgres であるふりをしません — 内部では依然として Query/Scan を通して読み取るので、 各クエリのコストを意識し続けられ、DynamoDB のアクセスモデルを隠すのではなく強制します。

  • INNER JOINLEFT JOIN のみ — ON の対象属性はパーティションキーまたは GSI パーティションキーでなければなりません。RIGHT / FULL / CROSS / カンマ結合はありません。
  • 自己結合はまだなし、サブクエリなし、派生テーブルなし、ウィンドウ関数なし。
  • 結合と射影はスカラー属性に対して動作します。

生の API のための条件とキー式を組み立てるだけ — 完全な SQL 文ではなく — でよいなら、 DynamoDB 式ビルダーが PartiQL の表層なしで正しい FilterExpression / KeyConditionExpression を生成します。

テーブルを探索、デバッグ、分析するための DynamoDB SQL クライアント が目標なら、 Workbench がそのギャップを埋めます — そして DynoTable の残りはその周りの完全な DynamoDB GUI です。

自分のテーブルに対して本物の SQL を実行するには DynoTable を試してください

FAQ

DynamoDB で SQL を実行できる? PartiQL(キーで SELECT/INSERT/UPDATE/DELETE する SQL 互換のサブセット)を実行できます。 完全な SQL — JOIN、GROUP BY、集計 — には、その上に SQL エンジンが必要です: Amazon Athena DynamoDB コネクタ、または DynoTable の SQL Workbench。

DynamoDB PartiQL は JOIN をサポートしている? いいえ。PartiQL の SELECT 構文は単一の FROM テーブルまたはインデックスを持ち、結合 文法はありません。結合には DynamoDB の上に重ねたエンジンが必要です。

PartiQL は GROUP BY や COUNT、SUM のような集計をサポートしている? いいえ。GROUP BY 句はなく、唯一の「集計」関数は SIZE(1 アイテムの属性のバイトサイズ) です。行をまたぐ COUNTSUMAVGMINMAX はサポートされません。

DynamoDB は SQL それとも NoSQL? NoSQL — キーバリュー・ドキュメントストアです。PartiQL がその上に SQL 互換のクエリ言語を 追加しますが、DynamoDB にはリレーショナルエンジン、結合、集計はありません。

PartiQL はアドホッククエリに向いている? キーベースの検索には、はい。分析的なアドホッククエリ(カウント、ロールアップ、結合)には、 いいえ — PartiQL はそれらを表現できず、制約のない SELECT は黙ってフルテーブルスキャンに なります。

JOIN や GROUP BY を扱う DynamoDB SQL クライアントはある? はい — DynoTable の SQL Workbench はデスクトップからライブテーブルに対して JOIN/ GROUP BY/集計を実行し、Amazon Athena は AWS アカウントにデプロイするフェデレーテッド コネクタ経由でそれを行います。

更新日