SQL互換のクエリ言語「PartiQL」でDynamoDBを操作する

# 概要
DynamoDBに関して学習をしている際、「DynamoDBでSQLライクなクエリが使える言語がある」ということを知り、興味を持ったので調査をしてみました。
→参照記事：https://www.publickey1.jp/blog/20/awsdynamodbsqlsqlpartiql.html
![スクリーンショット 2024-01-01 22.15.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/2e21a8a3-e2c6-c049-7eef-3c91239f9a6c.png)

# PartiQLの特徴
AWS公式の説明には以下の記述がありました。
>As long as your query engine supports PartiQL, you can process structured data from relational databases (both transactional and analytical), semi-structured and nested data in open data formats (such as an Amazon S3 data lake), and even schema-less data in NoSQL or document databases that allow different attributes for different rows.
- SQLに似た構文で記述可能なクエリ言語
    - RDB以外の種類のDB（DynamoDB、DocumentDB、QLDBなど）に対してもSQLのようなクエリを実行することができる
    - 構造化データにとどまらず、半構造化データ（JSONなど）、ネストされたデータのようなデータ構造が複雑なデータセットに対してもクエリを実行することができる


# PartiQLを実際に触ってみる
今回はNoSQLデータベースであるDynamoDBにおいて、PartiQLを実際に使用してみます。
検証には[NoSQL Workbench](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/workbench.html)を使用します。

### NoSQL Workbench についての簡単な説明
Amazon DynamoDBなどのNoSQLデータベースを管理するためのビジュアライゼーションツール（[こちら](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/workbench.settingup.html)からダウンロードが出来ます。）
ダウンロード後の初期画面はこのような画面になっています。
![スクリーンショット 2024-01-04 180357.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/708ebc5d-efb0-326b-cecf-0764fa179441.png)
全て英語で書かれているので、「どこに何が書かれているのか」を注意して読み解く必要がありそうですが、そこまで難しい内容は書かれていないので読解にはそこまで困らない印象でした。

Amazon DynamoDBと書かれている部分に、「Launch」ボタンがあるので、ボタンを押下すると下記のような画面に遷移すると思います。
![スクリーンショット 2024-01-04 232712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/3dd74605-c937-3ad1-e3e6-d50a7d149269.png)
**Sample data models** の部分を見れば何となく分かるかも知れませんが、AWS側でサンプルのデータセットを用意してくれているようです。個人的にテスト用のテーブルやデータを作成するのは少し煩わしかったのでありがたいなと思いました。
今回の検証では、Ski Resort Data Modelを使用することにします。

:::note info
メニューバーに表示されている他の項目について（詳細については添付画像を参照）
**Data modeler**→各テーブルや、テーブルの属性についての情報（PK,SKなどの設定状況も）を閲覧
**Visualizer**→テーブルの情報を表形式で閲覧
**Operation builder**→実際にPartiQLでのクエリを記載し、その結果を閲覧
:::
【Data modeler】→マネジメントコンソール>DynamoDBからでもデータの定義は変更できるがこちらの画面からでも変更可能
![スクリーンショット 2024-01-04 233634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/8564fe07-3114-962b-f8e1-8ddcb6f9abeb.png)
【Visualizer】
![スクリーンショット 2024-01-04 234628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/96f0d3cc-5a82-0085-6980-cb4e049e9e45.png)
【Operation builder】→Runボタンでクエリが実行できる
![スクリーンショット 2024-01-04 234708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/7fb3d1e0-504c-d69a-9c53-f343e76e1fec.png)


### INSERT,SELECT, UPDATE, DELETE
標準のSQLとほぼ変わりなくINSERT,SELECT, UPDATE, DELETE構文を使用することが可能です。
ポイントは、下図のように**リストに対しても操作ができること**です。
下図では、OpenLifts（リスト）の0番目の要素をSELECTするクエリを書いており、正常に実行されていることが分かります。
ちなみにOpenLiftsは["16","13","10"]というような形でOpenLiftsカラムに格納されています。
（DynamoDBにおけるデータ型はNumbersetsです）
![スクリーンショット 2024-01-04 230123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/43df46f8-29f8-0666-17d6-ad1724c100f5.png)

:::note warn
エイリアスが使えない、Bulk insert(update,delete)ができない（＝一括でデータを操作することができない）、LIMITが使えないなど、一部標準のSQLでできることができないという制約はあるので注意が必要です。
:::

### PariQL特有の関数
PartiQL特有の関数について、簡単にまとめてみました。
#### Contains(AttributeName, 'XXX')
指定された属性が特定の値を含むかどうかを確認する
![スクリーンショット 2024-01-04 235615.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/07246c1d-3418-8c40-648d-609a3c7fa135.png)

#### attribute_type(AttributeName, 'XXX')
指定された属性名が存在するかどうかを確認する
![スクリーンショット 2024-01-05 000608.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/be224422-b65d-ca9d-9d1b-06f469a27fda.png)

#### attribute_exists(AttributeName)
指定された属性が存在するかどうかを確認する
![スクリーンショット 2024-01-04 173245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/90569d53-e254-7172-bbf3-8a0cbd25b09c.png)

#### attribute_not_exists(AttributeName)
指定された属性が存在しないかどうかを確認する
![スクリーンショット 2024-01-05 000222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/14c60f7a-01ca-be29-4444-bed3ce275231.png)

#### begins_with(AttributeName, 'XXX')
指定された属性の値が特定のプレフィックスで始まるかどうかを確認する
![スクリーンショット 2024-01-04 224003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3623937/e760ee5e-b078-c86c-f813-d18b9ddd3a75.png)

# 標準SQLとPartiQLの比較表
標準SQLとPartiQLの比較について表形式でまとめてみました。
| 機能 | 標準SQL | PartiQL |
|:-:|:-:|:-:|
| データモデル  | 厳格、テーブルベース  | スキーマレス、ドキュメントベース（JSON）  |
| ネストされたデータに対するクエリ  | 基本的にはできない  | 可能  |
| トランザクション  | サポート（ACID特性がある）  | 限定的<br>※DynamoDBの場合はJava SDK or AWS CLIを使えば実現できる([こちら](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html)を参照)  |
|  データ型の厳密さ | 厳格（データ型の定義が必要）  | 柔軟（スキーマレスなので）  |


# 最後に
今回は、PartiQLで出来ることについて簡単にまとめてみましたが、標準のSQLを使う場合と比較してほぼ遜色なくデータ操作ができ便利だなという印象でした。
とはいうものの、どういったときにPartiQLのクエリを使うと有効なのか、という深いところまでの理解には及んでいないので、引き続き学習を続けていきたいと思っています。
# 参考文献
https://www.publickey1.jp/blog/20/awsdynamodbsqlsqlpartiql.html
https://aws.amazon.com/jp/blogs/opensource/announcing-partiql-one-query-language-for-all-your-data/
https://www.integrate.io/jp/blog/the-sql-vs-nosql-difference-ja/