【実務・中級編】 配列型 (Array Types) – PostgreSQL

PostgreSQLの配列型(Array Types)を使いこなそう!〜現場の先輩が教える実践テクニック〜

お疲れ様です!データベースの世界へようこそ。今日は、PostgreSQLのちょっと変わった、でもめちゃくちゃ便利な「配列型」について、現場でよく使うコツなんかも交えながら、ざっくばらんにお話ししていこうと思います。

「配列型?なんか難しそう…」って思うかもしれませんが、大丈夫!これ、知ってると日々の開発がグッと楽になるんですよ。特に、一つのカラムに複数の値をまとめて格納したい!なんて場面で大活躍します。

なんで配列型? 〜一つのカラムに複数の値を格納したい!〜

例えば、商品の「タグ」を管理する時って、どうします?

  • `tags` というカラムに、カンマ区切りで「`python,web,api`」みたいに文字列として格納する?
  • それとも、タグごとに別のテーブルを作って、リレーションシップで繋ぐ?

もちろん、どちらの方法も間違いではありません。ただ、タグがそんなに多くない場合や、単純に「この商品にはこういうタグが付いてるよ」という情報をサクッと持っておきたいだけなら、配列型がとっても便利なんです。

配列型を使えば、一つのカラムに複数の値を、まるでリストみたいに格納できるんです。

配列型の定義方法 〜テーブル作成時にサクッと定義!〜

配列型を使うのは、テーブルを作成する時が一番簡単です。例えば、`products` テーブルに `tags` という配列型のカラムを追加してみましょう。

CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
tags TEXT[] — ここでTEXT型の配列型を指定!
);

どうです? `TEXT[]` って書くだけ。`INT[]` とか `NUMERIC[]` とか、他のデータ型にも `[]` をつけるだけで配列型にできるんです。簡単でしょ?

配列への値の格納 〜INSERT文でリストを放り込む!〜

値を入れる時も、普通にINSERTするだけ。配列リテラルっていう、 `{}` で囲まれた形式で値を指定します。

INSERT INTO products (name, tags) VALUES
(‘Webフレームワーク入門’, ARRAY[‘python’, ‘web’, ‘framework’]),
(‘REST API設計’, ARRAY[‘api’, ‘design’, ‘rest’]),
(‘初心者向けPython’, ARRAY[‘python’, ‘beginner’]);

`ARRAY[]` と書くのが一般的ですが、 `{}` だけで書ける場合もあります。ただ、`ARRAY[]` の方が明確で、他のデータベースとの互換性も考慮すると、個人的にはこちらをおすすめします。

配列要素へのアクセス 〜欲しい値だけピンポイントで取り出す!〜

ここからが面白いところ!配列に格納した値、どうやって取り出すの?って思いますよね。

1. インデックス指定 〜配列の「〇番目」を取り出す〜

配列の要素は、1から始まるインデックスで指定できます。

— ‘Webフレームワーク入門’ のタグの1番目(’python’)を取得
SELECT tags[1] FROM products WHERE name = ‘Webフレームワーク入門’;
— 結果: python

2. 全要素の展開 〜配列をバラバラにして取得〜

`unnest` 関数を使うと、配列の要素をそれぞれ行として展開できます。これ、JOINみたいに使えて便利なんですよ。

— 全ての商品のタグを、商品名と一緒にバラバラにして表示
SELECT name, unnest(tags) AS tag
FROM products;

— 結果例:
— name | tag
— —————— | ——–
— Webフレームワーク入門 | python
— Webフレームワーク入門 | web
— Webフレームワーク入門 | framework
— REST API設計 | api
— REST API設計 | design
— REST API設計 | rest
— 初心者向けPython | python
— 初心者向けPython | beginner

この `unnest`、後で紹介する検索条件にも使えるので、覚えておくと損はないですよ!

3. 特定の要素が含まれているか検索 〜IN演算子や=演算子〜

特定のタグが付いている商品を探したい、なんてよくあるケースですよね。

— ‘python’ というタグが付いている商品を探す
SELECT name FROM products WHERE ‘python’ = ANY(tags);
— または
SELECT name FROM products WHERE tags @> ARRAY[‘python’]; — @> は「包含」演算子

`ANY(配列)` は、配列のいずれかの要素と一致するかどうかを判定します。`@>` 演算子は、左辺の配列が右辺の配列をすべて含んでいるかを判定するので、今回のように単一要素の配列を指定すると、「その要素が含まれているか」をチェックできます。

4. 配列全体で検索 〜配列の比較〜

配列全体が一致するものを探すこともできます。

— タグが [‘python’, ‘web’, ‘framework’] と完全に一致する商品を探す
SELECT name FROM products WHERE tags = ARRAY[‘python’, ‘web’, ‘framework’];

配列操作関数 〜配列を賢く、柔軟に扱う!〜

PostgreSQLには、配列を操作するための便利な関数がたくさん用意されています。いくつか代表的なものを見ていきましょう。

1. `array_append` 〜要素を末尾に追加〜

配列の最後に新しい要素を追加したい時に使います。

— ‘REST API設計’ のタグに ‘v2’ を追加
UPDATE products
SET tags = array_append(tags, ‘v2’)
WHERE name = ‘REST API設計’;

SELECT tags FROM products WHERE name = ‘REST API設計’;
— 結果: {api,design,rest,v2}

2. `array_cat` 〜二つの配列を結合〜

二つの配列をくっつけて、一つの新しい配列を作ります。

— 既存のタグと新しいタグのリストを結合
SELECT array_cat(tags, ARRAY[‘tutorial’]) AS new_tags
FROM products
WHERE name = ‘初心者向けPython’;

— 結果: {python,beginner,tutorial}

3. `array_prepend` 〜要素を先頭に追加〜

`array_append` の逆で、配列の先頭に要素を追加します。

— ‘Webフレームワーク入門’ のタグの先頭に ‘japanese’ を追加
UPDATE products
SET tags = array_prepend(‘japanese’, tags)
WHERE name = ‘Webフレームワーク入門’;

SELECT tags FROM products WHERE name = ‘Webフレームワーク入門’;
— 結果: {japanese,python,web,framework}

4. `array_remove` 〜特定の要素を削除〜

配列から、指定した値を持つ要素をすべて削除します。

— ‘python’ というタグを削除
SELECT array_remove(tags, ‘python’) AS updated_tags
FROM products
WHERE name = ‘Webフレームワーク入門’;

— 結果: {japanese,web,framework}

5. `array_to_string` 〜配列を文字列に変換〜

配列の要素を、指定した区切り文字で連結して一つの文字列にします。

— タグをカンマ区切りで表示
SELECT array_to_string(tags, ‘,’) AS tags_string
FROM products
WHERE name = ‘Webフレームワーク入門’;

— 結果: japanese,web,framework

これは、アプリケーション側で表示する時なんかにも便利ですよね。

配列型の注意点 〜知っておきたい落とし穴〜

配列型、便利なんですけど、いくつか注意しておきたい点もあります。

  • インデックスは1から始まる: これは他の多くのプログラミング言語と違うので、ちょっと混乱するかも。意識しておきましょう。
  • NULLの扱い: 配列要素にNULLを指定すると、そのままNULLとして格納されます。
  • パフォーマンス: 配列型に大量のデータを格納したり、複雑な検索を頻繁に行うと、パフォーマンスが低下する可能性があります。特に、配列全体での検索や、`unnest` を多用するクエリは注意が必要です。
  • インデックスが効きにくい場合がある: 配列の特定の要素に対するインデックス作成は、通常の型よりも複雑になることがあります。必要に応じて、GINインデックスなどを検討する必要があります。

どんな時に使う? 〜実践的なユースケース〜

  • タグ付け: 商品、ブログ記事、ユーザープロフィールなどへのタグ付け。
  • 設定値: 複数の設定値やオプションをまとめて管理したい場合。
  • 履歴データ: 比較的単純な履歴(例:IPアドレスのリスト)を保持する場合。
  • 一時的なデータ: 処理の途中で一時的に複数の値をまとめておきたい場合。

まとめ 〜配列型を武器に!〜

PostgreSQLの配列型は、うまく使えば開発効率をグッと上げてくれる強力な武器になります。今回紹介した基本的な定義方法、要素へのアクセス、そして便利な操作関数をマスターすれば、きっとあなたの開発ライフがより豊かになるはずです。

もちろん、どんなデータ型にも言えることですが、使いどころを間違えるとパフォーマンスの低下を招くこともあります。だからこそ、どんな時に配列型が最適なのか、どんな時に別の設計(正規化されたテーブルなど)を選んだ方が良いのか、常に吟味しながら使っていくことが大切です。

さあ、今日からあなたもPostgreSQLの配列型マスターを目指しましょう!もし分からないことがあれば、いつでも聞いてくださいね。現場で待ってます!

コメント

タイトルとURLをコピーしました