初級読了 4 分

DynamoDB のための SQL と PartiQL の限界

DynamoDB は NoSQL のキーバリューストアですが、人が思う以上に SQL 形式の問いに答えます — そして 期待するほどには答えません。これは正直な地図です。DynamoDB 上の SQL で実際に標準で得られるものは 何か、どこで止まるのか、そしてネイティブのサーフェスでは表現できない JOIN / GROUP BY / 集計の クエリを実行するわずかな方法です。

DynamoDB を SQL でクエリできるのか?

部分的には。DynamoDB は を備えています。これはキーによる SELECT/INSERT/UPDATE/DELETE のための SQL 互換言語で、SELECT * FROM "Orders" WHERE OrderID = 100 は動作します。ただしそれは DynamoDB API の上に載る SQL 互換のサーフェスであって、 SQL エンジンではありません — AWS は サブセット しかサポートしないため、JOINGROUP BYCOUNT(*) は対象外です。それらには、上に載せたエンジンが必要になります。

AWS は PartiQL を 「Amazon DynamoDB のデータを選択、挿入、更新、削除するための SQL 互換のクエリ言語」 と説明していますが、「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 つのネイティブ操作に畳み込まれます。

パーティションキーの等価条件を持たない SELECT は、テーブル全体の Scan にコンパイルされます。 us-east-1 のオンデマンドでは、評価したアイテムごとに結果整合性で 4 KB あたり 0.5 RCU が 課金されます — 2 KB の行が入った 500 MB のテーブルなら、WHERE フィルターが結果を絞る 前におよそ 125,000 RCU です。PartiQL 形式の読み取りの単価は 料金計算ツールで確かめましょう。

記述するもの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 です。(スケジュールされた 分析には、DynamoDB の Amazon Redshift へのゼロ ETL 統合も SQL の結合と集計を実行します。)

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 ランタイムを通してマテリアライズし、その上で 単一の SELECT を、デスクトップ上でローカルに実行します。

-- Runs in the DynoTable Workbench (NOT in 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 / カンマ結合はありません。
  • 自己結合はまだ、サブクエリ、派生テーブル、ウィンドウ関数もありません。
  • 結合と射影はスカラー属性に対して動作します。

完全な SQL ステートメントではなく、生の API 向けの条件式とキー式を組み立てるだけでよいなら、 DynamoDB Expression Builder が PartiQL のサーフェスをまったく 使わずに正しい FilterExpression / KeyConditionExpression を生成します。

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

DynoTable を試して、自分のテーブルに対して本物の SQL を実行しましょう。

よくある質問

DynamoDB で SQL を実行できますか? PartiQL は実行できます。これは SQL 互換のサブセット(キーによる SELECT/INSERT/UPDATE/DELETE)です。 JOIN、GROUP BY、集計には、上に載せた SQL エンジンが必要です。Amazon Athena DynamoDB コネクタ、または DynoTable の SQL Workbench — INNER JOIN/LEFT JOIN を備えた単一 SELECT の 方言で、CTE、UNION、サブクエリはありません。

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 アカウントにデプロイするフェデレーテッド コネクタ経由でそれを行います。

更新日