CodeGym /コース /SQL SELF /配列とJSONBの比較

配列とJSONBの比較

SQL SELF
レベル 36 , レッスン 0
使用可能

配列とJSONBの比較

今日は配列についてもっと深く理解して、さらにJSONBと比べてみて、それぞれの強み・弱みや、実際の課題でどう使い分けるのがベストかを考えてみよう。

配列 vs JSONB:データのミニカメたち vs 箱入りフレキシビリティ

もう知ってると思うけど、PostgreSQLの配列には同じ型の値だけを入れられるんだ。たとえば数字、文字列、日付の配列とか。例:学生の成績リスト、全部数字だよね。

-- 学生とその成績のテーブル
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades INTEGER[]    -- 成績の配列
);

JSONBは配列と違って、データをJSON構造で保存するんだ。JavaScriptのobjectっぽいけど、パースもインデックスも速いのがメリット。JSONBには順序付きリストも、キーと値のobjectも入れられるよ。

-- 学生とそのいろんなデータのテーブル
CREATE TABLE students_details (
    id SERIAL PRIMARY KEY,
    name TEXT,
    details JSONB  -- フレキシブルなJSON構造
);

JSONBのデータ例:

{
    "grades": [90, 82, 77],
    "address": {
        "city": "Berlin",
        "zip": "352912"
    }
}

つまり、配列は値のリストをシンプルに扱うためのもので、JSONBはもっと複雑なデータに対応できるんだ。

配列とJSONBの主な違い

特徴 配列 JSONB
構造のタイプ リニアなデータ構造 階層的なデータ構造
要素の型 一つのデータ型だけ いろんなデータ型
構造のサイズ 固定(リニア) フレキシブル、リストやobjectもOK
アクセス速度 固定データなら速い 複雑な検索はちょい遅い
インデックス インデックス対応バッチリ GINタイプのインデックスが必要
用途 シンプルなリストや値の配列 複雑なデータ:ネストobject/リスト

じゃあ、実際どう使うのか見てみよう。

配列を使うときは?

たとえば本のデータベースがあって、1冊の本が複数ジャンルに属する場合。ここは配列がピッタリ。

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title TEXT,
    genres TEXT[]    -- ジャンルの配列
);

-- 複数ジャンルの本を挿入する例
INSERT INTO books (title, genres)
VALUES ('1984', ARRAY['Dystopia', 'Political Fiction', 'Science Fiction']);

配列が向いてるのは、

  • データがきっちりリストで管理できるとき、
  • リストが小さくて同じ型(文字列や数字など)、
  • リストを保存・取り出すだけでOK(複雑な操作しない)

配列のメリット

  • 同じ型のデータをシンプルに保存できる。
  • タグ、カテゴリ、成績みたいな小さいリストに便利。

JSONBを使うときは?

今度は、本についてもっと複雑なデータ(ジャンル、ISBN、評価など)を保存したい場合。配列じゃ無理だから、ここはJSONBの出番!

CREATE TABLE books_details (
    id SERIAL PRIMARY KEY,
    title TEXT,
    details JSONB    -- 本の詳細をJSONBで
);

-- 複雑な本情報を挿入する例
INSERT INTO books_details (title, details)
VALUES (
    '1984',
    '{"genres": ["Dystopia", "Political Fiction", "Science Fiction"],
      "isbn": "9780451524935",
      "rating": 8.9}'
);

JSONBが向いてるのは、

  • 複雑またはバラバラなデータ(数字、文字列、リスト、object)を保存したいとき、
  • テーブル構造を変えずにパラメータを追加したいとき、
  • ネストしたデータ(住所、特徴、設定など)を保存したいとき。

JSONBのメリット

  • 超フレキシブル。テーブル構造を変えずに新しいキーや値を追加できる。
  • APIのJSONレスポンスみたいな複雑なデータ保存に最適。

配列とJSONBの選び方

同じ型のリストだけ保存したいなら配列を使おう。 例えば:

-- イベント参加者IDの保存
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    participant_ids INTEGER[]
);

データがバラバラ・複雑ならJSONBがベター。 例えば:

-- 住所付きの顧客情報保存
CREATE TABLE customers (
    id SERIAL PRIMARY KEY,
    info JSONB
);

インデックスの仕組みは配列とJSONBで違うよ。 配列にはGINインデックスがよく使われて、JSONBにはデータ構造によってGINBTREEが使われる。

パフォーマンス

配列は典型的な検索タスクなら速い。JSONBはちょい遅いけどフレキシビリティが強み。要素(ジャンルやIDなど)を探すだけなら配列の方が速いよ:

-- 配列+GINインデックスの利用
CREATE INDEX idx_genres ON books USING GIN(genres);

-- ジャンルで本をフィルタ
SELECT * FROM books WHERE genres @> ARRAY['Science Fiction'];

データの存在チェック

JSONBはキーでのフィルタがもっと柔軟:

-- "genres"キーの存在チェック
SELECT * FROM books_details WHERE details ? 'genres';

-- リスト内要素の存在チェック
SELECT * FROM books_details WHERE details->'genres' ?| ARRAY['Fantasy', 'Dystopia'];

配列は値を直接探せる:

-- 配列内要素の存在チェック
SELECT * FROM books WHERE genres @> ARRAY['Fantasy'];

構造のフレキシビリティ

データが複雑でネストしてるならJSONBが最強:

{
    "genres": ["Fantasy", "Adventure"],
    "ratings": {"goodreads": 8.5, "amazon": 4.7}
}

配列だと、こういうのは正規化や追加カラムなしじゃ無理。

結局、配列とJSONBはライバルじゃなくて、用途が違うツールなんだ。データがリストっぽいなら配列。複雑・ネスト・バラバラなデータなら迷わずJSONB。大事なのはパフォーマンスとインデックスも忘れないこと!

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION