データの構造が普通の文字列や数字に収まらないことってあるよね。たとえば、ユーザーが趣味のリストを持ってたり、プロフィールのカスタム設定や注文のネストされたパラメータがあったり。こういうののために専用のテーブルをガチガチに作るのは面倒。そこで役立つのがJSONなんだ。
PostgreSQLはこういうデータを扱うためにJSONとJSONBの2つのフォーマットをサポートしてる。どっちも1つのカラムに構造化データを保存できるけど、重要な違いがあるんだ。
どう動くのか、どっちを使うべきか、どんなことができるのかを見ていこう。
JSONって何?
JSON(JavaScript Object Notation)は、構造化データをわかりやすく表現するために作られたテキスト形式のデータ交換フォーマットだよ。Webアプリを触ったことあるエンジニアなら絶対見たことあるやつで、「人間が読めるし」「コンピュータも簡単にパースできる」って感じ。PostgreSQLでは構造化データの保存や処理に使われてる。
JSONオブジェクトの例を見てみよう:
{
"name": "Alex Lin",
"age": 25,
"skills": ["SQL", "PostgreSQL", "JavaScript"],
"address": {
"city": "Berlin",
"postal_code": "10115"
}
}
メモ:JSONはただのテキストだけど、ちゃんとルールがある。たとえば、キー名は必ずクォートで囲むとかね。
JSONB: バイナリJSON
JSONBは「バイナリJSON」って意味で、PostgreSQLでサポートされてる。JSONと違って、JSONBはインデックスが使えて、検索や変更が速いように最適化されてる。PostgreSQLでのJSONとJSONBの主な違いは保存方法にあるよ:
- JSONは渡したデータをそのままテキスト文字列として保存する。
- JSONBはデータをバイナリ形式に変換して、ほとんどの操作でより効率的に扱える。
JSONBだと、フィルタリングやインデックス、複雑なネスト構造の比較なんかができるようになる。
JSONBの主なメリット
なんでJSONじゃなくてJSONBを選ぶの?理由はいくつかあるよ:
- 検索やフィルタが速い
JSONBはデータの取り出しが速い。たとえば、大きなオブジェクト配列があっても、全部なめなくても必要な要素をすぐ見つけられる。
- インデックスが使える
インデックスを使えば、JSONBの中のキーや値で爆速検索ができる。JSON(テキスト形式)だとインデックスは使えないんだ。
- ネストデータの扱いがラク
JSONBはネスト構造との相性が抜群。階層データのためにテーブルを増やしまくる必要がなくて、全部コンパクトにまとめられる。
JSONとJSONB、どっちを使う?
- JSONはデータを「そのまま」テキストで保存したいときに使うといい。たとえば、データの正確な記録が大事とか、ほとんど加工しない場合。
- JSONBは、データの検索・フィルタ・更新をガンガンやりたいときや、インデックスが必要なときに便利。
JSONオブジェクトの例
いくつかJSONオブジェクトの例を見て、どんな構造が作れるかチェックしよう。
シンプルなJSONオブジェクト。
キーと値の構造:
{
"name": "エカテリーナ",
"age": 29
}
JSONの配列
JSONは配列もサポートしてる:
{
"skills": ["Python", "SQL", "データ分析"]
}
ネストされたオブジェクト
JSONなら複雑なデータをまとめて保存できる:
{
"name": "アンドレイ",
"contacts": {
"email": "andrey@example.com",
"phone": "+79012345678"
}
}
配列とオブジェクトの組み合わせ
配列とオブジェクトを組み合わせることもできる:
{
"team": [
{
"name": "エレナ",
"role": "マネージャー"
},
{
"name": "パベル",
"role": "開発者"
}
]
}
JSONとPostgreSQL
PostgreSQLはJSONを扱うために2つのデータ型を用意してる:
JSON: テキスト形式。JSONB: バイナリ形式。
JSONとJSONBカラムを持つテーブルの作成
PostgreSQLのテーブルでJSON/JSONBをどう使うか見てみよう。たとえば、会社の従業員情報を保存するテーブルを作るとする:
-- JSONとJSONBカラムを持つテーブルを作成
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
details JSON, -- テキストJSON
profile JSONB -- バイナリJSON
);
パッと見だとカラムの違いが分かりにくいけど、実は違う。JSONはデータをそのまま保存したいときに最適、JSONBはフィルタや検索に強い。
-- データを挿入
INSERT INTO employees (name, details, profile)
VALUES
('Alex Lin', '{"age": 30, "city": "タリン"}', '{"skills": ["SQL", "PostgreSQL"], "hobby": "サッカー"}'),
('Maya Novak', '{"age": 25, "city": "リガ"}', '{"skills": ["Python", "機械学習"], "hobby": "読書"}');
JSONBデータの取り出し
JSONBからデータを取り出すには、専用の関数を使うよ(これは次の講義で詳しくやる)。たとえば、従業員のスキルを知りたいとき:
-- スキルの取り出し
SELECT name, profile->'skills' AS skills
FROM employees;
結果:
| name | skills |
|---|---|
| Alex Lin | ["SQL", "PostgreSQL"] |
| Maya Novak | ["Python", "機械学習"] |
リアルな現場でのJSONの使い道
JSON(とJSONB)は実際のアプリでもめっちゃ使われてる。たとえば:
- APIとマイクロサービス。JSONはRESTful APIでのデータやりとりの標準フォーマット。PostgreSQLは保存も処理もバッチリ対応。
- データ統合。いろんなシステムからデータを受け取るDBなら、JSONBで扱うと便利。
- 複雑な構造の管理。たとえば、アンケートデータやユーザー設定、企業メタデータの保存にJSONBはピッタリ。
GO TO FULL VERSION