
PostgreSQL の JSONB データタイプについて、初級エンジニア向けの入門記事です。実例を交えながら、JSONB の基本的な使い方から、クエリ、インデックスまでを解説します。
はじめに
近年、アプリケーション開発では構造化データだけでなく、柔軟なスキーマを持つドキュメント型データの扱いが増えています。PostgreSQL が提供する JSONB(binary JSON)型は、JSON 形式のデータを高速に格納・検索できる強力な機能です。本記事では、JSONB の特徴と基本操作を具体例とともに解説します。
1. JSON と JSONB の違い
特徴 | JSON | JSONB |
---|---|---|
格納形式 | テキスト | バイナリ |
バリデーション | INSERT 時にバリデート | INSERT 時にバリデート |
読み込み性能 | パースが必要 | 直接読み込み可能 |
インデックス対応 | 部分対応 | GIN/BTREE インデックスが利用可能 |
データ順序保持 | 元のキー順序を保持 | ソート済みキー順序(順序は保持しない) |
- JSON は挿入時にバリデーションのみ行い、文字列として保存します。
- JSONB は内部で最適化されたバイナリ形式で保存され、検索性能やインデックス性能に優れます。
2. JSONB カラムの定義
まずはテーブルに JSONB 型のカラムを追加してみましょう。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
profile JSONB
);
上記の例では、users.profile
カラムに任意の JSON 構造を格納できます。
3. データの挿入例
INSERT INTO users (profile) VALUES (
'{
"name": "山田太郎",
"age": 30,
"skills": ["Python", "PostgreSQL", "Docker"],
"address": {
"city": "東京",
"zip": "100-0001"
}
}'
);
- JSON 文字列をシングルクォートで囲み、直接挿入します。
- PostgreSQL 側でバリデーション後、バイナリ形式に変換されて保存されます。
4. 基本的なクエリ操作
4.1 キーでのアクセス
->
演算子:JSONB オブジェクトから オブジェクト を取得->>
演算子:JSONB オブジェクトから テキスト を取得
-- JSONB オブジェクトをそのまま取得
SELECT profile->'address' AS address
FROM users
WHERE id = 1;
-- テキストとして取得
SELECT profile->>'name' AS name
FROM users
WHERE id = 1;
4.2 ネストしたキーへのアクセス
-- JSONB パス演算子 #>> を利用
SELECT profile#>>'{address,city}' AS city
FROM users
WHERE id = 1;
4.3 配列要素の取得
-- 配列の 2 番目の要素(0 始まり)
SELECT profile->'skills'->>1 AS second_skill
FROM users
WHERE id = 1;
5. JSONB 検索の応用
5.1 特定キーの存在チェック
-- 'skills' キーが存在するレコードを抽出
SELECT id
FROM users
WHERE profile ? 'skills';
5.2 配列内要素の存在チェック
-- skills 配列に 'Docker' が含まれるレコード
SELECT id
FROM users
WHERE profile->'skills' ? 'Docker';
5.3 多重条件による検索
-- name が "山田太郎" かつ city が "東京" のレコード
SELECT id
FROM users
WHERE profile->>'name' = '山田太郎'
AND profile#>>'{address,city}' = '東京';
6. インデックスによる高速化
JSONB で大量データを扱う場合、インデックスを利用しないと検索が遅くなります。GIN インデックスを設定しましょう。
-- 全体インデックス(任意のキー検索に有効)
CREATE INDEX idx_users_profile_gin
ON users
USING GIN (profile);
-- 特定キーに最適化した部分インデックス
CREATE INDEX idx_users_profile_skills
ON users
USING GIN (profile->'skills');
- 全体インデックス:
?
,@>
,->
演算子など多彩な検索に対応 - 部分インデックス:特定パスに限定したインデックスで、ディスク使用量を抑制可能
7. 実践的ユースケース
- 柔軟なユーザープロファイル管理
固定スキーマでは対応しきれない多様な属性を JSONB で管理。 - イベントログの保存
ログ構造が頻繁に変わる場合に JSONB で簡単保存・検索。 - 設定データの格納
アプリケーション設定を JSONB にまとめて保管し、一括取得。
8. 注意点
- スキーマレスの乱用に注意:何でも JSONB に放り込むと、参照整合性が失われ、クエリが複雑化します。
- インデックスの設計:適切なインデックスを作成しないと、性能が劣化します。
- データの成長管理:巨大な JSONB ドキュメントはメモリ使用量を増加させるため、分割ストレージを検討してください。
まとめ
JSONB は、柔軟かつ高速なドキュメント型データ管理を可能にする PostgreSQL の強力な機能です。基本的なクエリ演算子やインデックスを理解し、実際のユースケースに適切に適用することで、スキーマの変化が激しいデータにも対応できます。まずは小規模なテーブルで試し、徐々に運用設計へ組み込んでいきましょう。