「配列型(Array Types)を使いこなして、PostgreSQLのポテンシャルを解放しよう」
やあ。今日はPostgreSQLのちょっと「攻めた」機能、配列型について話をしようか。
RDBMSの設計において「1対多」の関係を作るなら、基本は正規化して別テーブルに切り出すのが鉄則だよな。それは今でも変わらない。でも、現場で開発していると、「わざわざ別テーブルを切るほどじゃないんだけど、かといってJSONで持つのもクエリが面倒だな……」なんてシチュエーション、あるよね。
そんなとき、PostgreSQLの配列型は最高にクールな選択肢になるんだ。今日はその勘所と、実務でハマらないためのコツを伝授するよ。
1. 配列型の基本:型定義は直感的だ
PostgreSQLの配列型は、ほとんどの型に対して後ろに `[]` をつけるだけで定義できる。
CREATE TABLE user_profiles (
id serial PRIMARY KEY,
username text,
tags text[], — 文字列の配列
login_history int[] — 整数の配列
);
データの挿入も、おなじみの配列リテラルを使えばいい。
INSERT INTO user_profiles (username, tags)
VALUES (‘satoshix’, ‘{“postgresql”, “ruby”, “rust”}’);
これだけで、`tags` カラムの中に3つの要素が綺麗に収まる。シンプルだろう?
2. 実務で光る!配列操作の魔法
配列型が本当に威力を発揮するのは、その「操作演算子」の豊富さだ。これを知っているかどうかで、クエリの書きやすさが劇的に変わる。
特定の要素を含むかチェックする (`@>`)
「このタグを持っているユーザーを検索したい」という要件は頻出だ。ここで `LIKE` を使うなんて野暮なことはせず、包含演算子 `@>` を使おう。
— “postgresql” タグを持つユーザーを探す
SELECT FROM user_profiles WHERE tags @> ‘{“postgresql”}’;
これ、インデックスさえ貼っておけば爆速なんだ。後述するけど、ここが配列型の強みだよ。
配列同士の重なりを調べる (`&&`)
「興味関心が1つでも被っているユーザー」を探すようなケースだ。
— 検索条件のいずれかのタグを持つユーザー
SELECT FROM user_profiles WHERE tags && ‘{“python”, “rust”}’;
要素を追加・削除する (`array_append` や `array_remove`)
アプリ側で配列を操作して全件アップデートするよりも、DB側で完結させたいケースも多いよね。
— タグを追加
UPDATE user_profiles
SET tags = array_append(tags, ‘go’)
WHERE id = 1;
3. 多次元配列という名の「沼」と「武器」
実はPostgreSQLは多次元配列も扱える。`text[][]` のように定義するんだ。
ただ、正直に言うと、実務で多次元配列を多用するのはあまりおすすめしない。データ構造が複雑になりすぎて、後からメンテする人間が泣くことになるからね。
もし「座標データ」や「行列計算」が必要な場合以外は、素直に一次元配列で運用するのが、チーム開発における「平和」の秘訣だ。
4. パフォーマンスの要:GINインデックス
ここが一番大事なポイントだ。配列型を使うなら、GIN (Generalized Inverted Index) インデックスを絶対に忘れないでくれ。
普通のB-treeインデックスは「値そのもの」をインデックスするけど、配列の中身を検索対象にするならGINが最適だ。
CREATE INDEX idx_user_tags ON user_profiles USING GIN (tags);
これさえ貼っておけば、何百万件のデータがあっても `@>` 演算子による検索は一瞬で終わる。「配列型は遅い」なんて言う奴がいたら、たいていこのインデックスを忘れているだけさ。
現場の先輩からのアドバイス
最後に、僕が実務で学んだ教訓を2つだけ伝えておく。
1. 「正規化」とのバランスを忘れるな
配列型は便利だけど、配列内の要素に対して「外部キー制約」をかけることはできない。データの整合性が厳密に求められるなら、迷わず別テーブルへ切り出そう。配列型は「属性」や「ログ的要素」に向いている。
2. 要素数はほどほどに
数千個の要素を持つような配列を作ると、メモリを食うしクエリのオーバーヘッドも増える。あくまで「数個〜数十個」の要素を扱うためのものだと割り切るのがスマートだ。
配列型を使いこなすと、PostgreSQLという強力な相棒の、また違った顔が見えてくるはずだよ。ぜひ、次回の設計で検討してみてくれ。
何か詰まったら、いつでも聞きに来るといい。応援しているよ!
コメント