1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Aurora DSQL が JSONB データ型をサポート!JSONB型を触ってみた。

1
Posted at

はじめに

2026 年 6 月 8 日、Amazon Aurora DSQL が JSONB データ型 をサポートしました!

DSQL はサーバーレスの分散 SQL データベースで、PostgreSQL 互換性を持ちますが、今回 JSONB が使えるようになったことで、柔軟なスキーマを持つデータも DSQL で管理できるようになりました。

この記事では AWS CDK(TypeScript)で DSQL クラスタを作成し、実際に JSONB テーブルを作って INSERT / SELECT まで試してみます!

また私自身が JSONB 型をあまり知らなかったので、JSONB の内容含めて解説します。

この記事で学べること

  • JSONB と JSON の違い
  • JSONB テーブルを作成して INSERT / SELECT を試す手順
  • ->, ->>, @> といった JSONB 演算子の使い方

前提知識・条件

  • 検証日: 2026 年 6 月 12 日
  • リージョン: ap-northeast-1(東京)

JSONB とは?

まず JSON とは

JSON(JavaScript Object Notation)は、構造化されたデータをテキスト形式で表現するフォーマットです。

API のレスポンスや設定ファイルなど、日常的にあちこちで使われていますね。

{
  "method": "POST",
  "path": "/users",
  "status": 201,
  "duration_ms": 45
}

PostgreSQL における JSON と JSONB の違い

PostgreSQL には JSONJSONB の 2 種類の型があります。

項目 JSON JSONB
保存形式 テキストそのまま バイナリ(分解済み)
空白・キー順 保持する 保持しない
重複キー 全て保持 最後の値が勝つ
書き込み速度 速い やや遅い(変換コストあり)
読み取り・クエリ速度 毎回パースが必要 高速
インデックス(GIN 等) 使えない 使える

JSONB は書き込み時に変換コストがかかりますが、読み取りとクエリ速度で有利です。

「スキーマが決まっていない柔軟なデータを格納しつつ、頻繁に検索したい」という場面でよく使われるみたいです。

なお、上の表は一般的な PostgreSQL の話です。

Aurora DSQL では現時点で JSONB カラムへの GIN インデックスは非対応になっています。詳しくは「まとめ」の制限事項をご覧ください。

DSQL での JSONB 圧縮

今回のアップデートでは、圧縮がデフォルトで有効になっていますが、INSERT / UPDATE のタイミングで自動的に圧縮されるので、意識せずにストレージ効率が上がります。

Aurora DSQL は json 列に自動的に圧縮を適用し、デフォルトでは INSERT および UPDATE オペレーション中に大きな json 値を圧縮します。1 MiB の制限は圧縮後のサイズに適用されるため、1 MiB を大幅に超える json 値でも、圧縮後のサイズが制限値未満であれば保存できます。

圧縮を無効にしたい場合は STORAGE キーワードで制御できます。

ALTER TABLE events ALTER COLUMN payload SET STORAGE EXTERNAL;

やってみた

では、実際に動作確認してみます。

今回使うものは次のとおりです。

  • AWS CDK(TypeScript): DSQL クラスタの作成
  • AWS マネジメントコンソール(クエリエディタ): SQL の実行

Step 1. CDK で DSQL クラスタを作る

CDK プロジェクトを TypeScript で用意します。

スタックの定義はシンプルです。

import * as cdk from 'aws-cdk-lib/core';
import * as dsql from 'aws-cdk-lib/aws-dsql';
import type { Construct } from 'constructs';

export class DsqlJsonbStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const cluster = new dsql.CfnCluster(this, 'DsqlCluster', {
      deletionProtectionEnabled: false,
      tags: [
        { key: 'Name', value: 'dsql-jsonb-cluster' },
        { key: 'Project', value: 'dsql-supports-jsonb' },
      ],
    });

    new cdk.CfnOutput(this, 'ClusterIdentifier', {
      value: cluster.attrIdentifier,
      description: 'Aurora DSQL クラスタの識別子',
    });

    new cdk.CfnOutput(this, 'ClusterEndpoint', {
      value: cluster.attrEndpoint,
      description: 'Aurora DSQL クラスタのエンドポイント',
    });
  }
}

Step 2. DSQL へ接続

AWS マネジメントコンソールから Aurora DSQL のクラスタ一覧を開き、作成したクラスタを選択します。「クエリエディタ」タブからそのまま SQL を実行できます。

「接続」から対象のクラスタを選ぶだけです。

CleanShot 2026-06-12 at 04.59.51@2x.png

Step 3. JSONB テーブルを作成

クエリエディタで CREATE TABLE を実行します。payload カラムに JSONB 型を指定するだけで、圧縮は自動的に有効になります。

CREATE TABLE events (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  event_type TEXT NOT NULL,
  payload JSONB NOT NULL,
  created_at TIMESTAMPTZ DEFAULT now()
);

CleanShot 2026-06-11 at 18.35.46.png

Step 4. データを INSERT / SELECT

データを INSERT する

API リクエストログ、設定変更、エラーといった種類の異なるイベントをまとめて INSERT してみます。スキーマが違っても JSONB なので全部同じカラムに入るのが便利ですね。

INSERT INTO events (event_type, payload) VALUES
  ('api_request', '{"method": "POST", "path": "/users", "status": 201, "duration_ms": 45}'),
  ('api_request', '{"method": "GET", "path": "/orders", "status": 200, "duration_ms": 120}'),
  ('config_change', '{"key": "feature_flag", "old_value": false, "new_value": true, "changed_by": "admin"}'),
  ('error', '{"code": "TIMEOUT", "service": "payment", "retry_count": 3, "details": {"endpoint": "/charge", "timeout_ms": 5000}}');

CleanShot 2026-06-11 at 18.36.28.png

全件取得

まず全件 SELECT してみます。

SELECT * FROM events;

payloadは [object Object] となっており、内容は見れなみたいですね。

CleanShot 2026-06-11 at 18.38.30.png

->> 演算子でフィールドをテキストとして取得

->> は JSONB のフィールドをテキストとして取得する演算子です。

SELECT
  event_type,
  payload->>'method' AS method,
  payload->>'path' AS path,
  (payload->>'duration_ms')::int AS duration_ms
FROM events
WHERE event_type = 'api_request';

結果はこんな感じになります。

event_type method path duration_ms
api_request POST /users 45
api_request GET /orders 120

CleanShot 2026-06-11 at 18.39.13.png

@> 演算子で包含検索

@> は「左辺が右辺の JSONB を含むか」を検索する演算子です。status: 200 のレコードだけを絞り込んでみます。

SELECT * FROM events
WHERE payload @> '{"status": 200}';

status キーを持つレコードは api_request の 2 件だけですが、 値が 200 のデータは1重圏のみですので、"status": 200 の 1 件だけ返ってきます。

CleanShot 2026-06-11 at 18.39.30.png

ネストしたフィールドへのアクセス

-> を連続させることでネストしたフィールドにアクセスできます。

SELECT
  payload->'details'->>'endpoint' AS endpoint,
  payload->'details'->>'timeout_ms' AS timeout_ms
FROM events
WHERE event_type = 'error';

error レコードの details オブジェクト内の値が取れました。

endpoint timeout_ms
/charge 5000

CleanShot 2026-06-11 at 18.39.46.png

まとめ

CDK で Aurora DSQL クラスタを作り、JSONB テーブルへのデータ操作まで試してみました。

  • JSONB カラムの定義はただ型を JSONB にするだけ。圧縮は自動なので意識しなくていい
  • ->, ->>, @> などの PostgreSQL 演算子がそのまま動く
  • スキーマの違うイベントを 1 つのテーブルで管理できるのは柔軟で便利!

JSONB が使えることで、「ログ系データは別サービスで管理してたけど DSQL に統合できそう」みたいなユースケースが広がった印象です。Aurora DSQL はサーバーレスで運用負荷がほぼゼロなので、こういう用途と相性がいいかなと感じています。

なお、簡単な動作確認時には気になりませんでしたが、ドキュメントで確認した制限事項も最後に記載しておきます。

制限事項

  • JSONB の最大サイズは 1 MiB(圧縮後)
  • PostgreSQL の JSON 関数・演算子はすべてサポート
  • json_populate_record / jsonb_populate_recordset 等はカスタム複合型(CREATE TYPE)では未対応。テーブル/ビューの行型でのみ動作する模様
  • JSONB カラムへの GIN インデックスは現時点では非対応

この記事が誰かのお役に立てると幸いです、最後まで読んでいただきありがとうございました!!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?