PostgreSQL | SQLite+MySQL経験者向け、30日で習得するPostgreSQL:プロレベル運用 - Day27 拡張機能

SQL PostgreSQL
スポンサーリンク

Day27 前半のゴール

「“PostgreSQLはただのRDB”から“機能を足せるプラットフォーム”だと気づく」

今日のテーマは「拡張機能(extension)」、そして代表例としての PostGIS(地理情報)です。
ここまで学んできたのは、いわば「素のPostgreSQL」。
Day27 では、「PostgreSQLは“機能を後から足せるプラットフォーム”でもある」という視点を手に入れてもらいます。

前半のゴールはこうです。
拡張機能(extension)とは何かを、自分の言葉で説明できる。
CREATE EXTENSION で「DBに機能をインストールする」イメージを持てる。
PostGIS が「地理情報を扱うための拡張」であることと、そのざっくりした使いどころをイメージできる。

まずは、「拡張機能ってそもそも何?」からいきます。


拡張機能とは何か

「PostgreSQLに“新しい脳みそ”を後付けする仕組み」

拡張機能(extension)は、一言でいうと「PostgreSQLに後から追加できる機能パック」です。
アプリでいう「プラグイン」や「モジュール」に近いイメージです。

拡張機能が追加できるものは、かなり幅広いです。

新しいデータ型(例:地理情報、JSONの強化版、暗号化用の型など)
新しい関数・演算子(例:距離計算、統計関数、暗号化・復号関数など)
新しいインデックス方式(例:地理情報向けのインデックス)
新しい集約関数やユーティリティ

これらを「PostgreSQL本体を改造することなく」「DBごとにオン・オフできる」ようにするのが、拡張機能の仕組みです。

重要なのは、「PostgreSQLは“拡張前提で設計されたRDB”」だということです。
つまり、「標準機能+必要な拡張を組み合わせて、自分たちの用途に最適化できるプラットフォーム」として考えると、見え方が変わります。


CREATE EXTENSION のイメージ

「OSにパッケージを入れてから、“このDBで使う”と宣言する」

拡張機能を使う流れは、ざっくり二段階です。

サーバ側(OS側)に拡張モジュールをインストールする。
特定のデータベースの中で CREATE EXTENSION を実行して、「このDBで使う」と宣言する。

OS側へのインストールは、環境によって違います(apt / yum / brew など)。
ここでは、「サーバ管理者がやる作業」として一旦箱に入れておきます。

開発者としてよく触るのは、二段階目の CREATE EXTENSION です。

例えば、標準でよく使われる拡張 uuid-ossp を有効化する場合は、こう書きます。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SQL

これで、「このデータベースの中で uuid-ossp が使えるようになる」わけです。
新しい関数(uuid_generate_v4() など)が増え、UUIDを簡単に生成できるようになります。

ここでのポイントは、「拡張は“DBごとに有効化する”」ということです。
同じPostgreSQLサーバ上でも、「このDBではPostGISを使う」「あのDBでは使わない」といった切り分けができます。


PostGISとは何か

「PostgreSQLを“地理情報データベース”に変える拡張」

PostGIS は、PostgreSQLの拡張機能の中でも超有名な存在です。
一言でいうと、「PostgreSQLを地理情報(GIS)対応にする拡張」です。

PostGISを入れると、ざっくりこんなことができるようになります。

位置情報を表す専用のデータ型(POINT, LINESTRING, POLYGON など)が使える。
「この2点の距離は?」「この点はこのエリアの中か?」といった空間クエリが書ける。
地図アプリや位置情報サービスで必要な処理を、DB側で効率よく実行できる。

つまり、「緯度経度をただの数値として持つ」のではなく、
「空間として意味のあるデータ」として扱えるようになるわけです。

イメージとしては、「PostgreSQLに“地図の脳みそ”を付ける」のがPostGISです。


例題:店舗の位置情報をPostGISで持つイメージ

「POINT型で“緯度経度”を1つの値として扱う」

具体的なイメージを持つために、「店舗の位置情報」を扱う例を考えます。

PostGISを使わない場合、店舗テーブルはこんな感じになりがちです。

CREATE TABLE shops (
  id        bigserial PRIMARY KEY,
  name      text NOT NULL,
  lat       double precision NOT NULL,
  lon       double precision NOT NULL
);
SQL

緯度(lat)と経度(lon)を別々のカラムで持っています。
これでも動きますが、「距離計算」「範囲検索」などをやろうとすると、
毎回「地球は球体で〜」みたいな計算式を自分で書く必要が出てきます。

PostGISを使うと、こう書けます。

CREATE TABLE shops (
  id        bigserial PRIMARY KEY,
  name      text NOT NULL,
  location  geometry(Point, 4326) NOT NULL
);
SQL

ここで出てきた geometry(Point, 4326) が、PostGISのデータ型です。

geometry
→ 「空間オブジェクト」を表す基本型。

Point
→ 点(位置)を表すサブタイプ。

4326
→ 世界測地系(WGS84)、つまり一般的な緯度経度の座標系を表す番号。

これにより、「location カラム1つで“位置情報”を表す」ことができます。

INSERTするときは、PostGISの関数を使います。

INSERT INTO shops (name, location)
VALUES (
  'テストカフェ',
  ST_SetSRID(ST_MakePoint(139.7000, 35.6895), 4326)
);
SQL

ST_MakePoint(経度, 緯度) で点を作り、
ST_SetSRID(..., 4326) で「これはWGS84の座標だよ」と教えています。

ここでの重要ポイントは、「PostGISを使うと、緯度経度を“ただの数値”ではなく“空間オブジェクト”として扱える」ということです。


例題:ある地点から半径1km以内の店舗を探す

「“距離で検索する”をSQLで書ける気持ちよさ」

PostGISの真価は、「空間クエリ」が書けるところにあります。
例えば、「この地点から半径1km以内の店舗を探したい」という要件を考えます。

地点(ユーザーの現在地など)を、経度・緯度で持っているとします。

-- 東京駅あたりを仮の現在地とする
SELECT *
FROM shops
WHERE ST_DWithin(
  location::geography,
  ST_SetSRID(ST_MakePoint(139.7671, 35.6812), 4326)::geography,
  1000
);
SQL

ここで使っている ST_DWithin は、「2つの位置が、指定した距離以内かどうか」を判定する関数です。

location::geography
→ geometry を geography にキャストして、「地球の丸さを考慮した距離計算」をするための型変換。

ST_SetSRID(ST_MakePoint(…), 4326)::geography
→ 比較対象の点(現在地)を geography 型に変換。

1000
→ 距離(メートル)。ここでは1km。

このクエリは、「東京駅から1km以内にある店舗」を全部返してくれます。

もしPostGISなしで同じことをやろうとすると、
自分で距離計算の式を書き、インデックスも工夫しないといけません。
PostGISは、そのあたりを「地理情報の専門家が作ったロジック」と「専用インデックス」で肩代わりしてくれます。

ここでの学びは、「拡張機能を入れると、“その分野の専門知識”をDBにインストールできる」ということです。


拡張機能を使うときの“責任の範囲”

「便利さの裏に、“依存する”という選択がある」

拡張機能は強力ですが、「入れた瞬間から、その拡張に依存する」ことになります。
これは、セキュリティ・運用・将来の移行の観点で、ちゃんと意識しておくべきポイントです。

運用面
バージョンアップ時に、「PostgreSQL本体+拡張」の互換性を確認する必要がある。
バックアップ・リストア時にも、「拡張が入っている前提」で環境を用意する必要がある。

セキュリティ面
拡張はC言語などで書かれていることが多く、「DBの中で動くネイティブコード」です。
信頼できる拡張だけを使う、不要な拡張は入れない、という判断が大事です。

移行面
将来、別のRDBMSに移行したくなったとき、
PostGISや特定拡張に強く依存していると、「移行コスト」が跳ね上がる。

だからこそ、「拡張を使うかどうか」は、
「その機能がどれだけ価値を生むか」と「その拡張にどれだけ縛られてもいいか」のバランスで決める必要があります。

PostGISレベルのメジャー拡張は、「依存してもいい」と判断されることが多いですが、
それでも「入れた瞬間から“PostgreSQL+PostGIS前提の世界”になる」という自覚は持っておきたいところです。


Day27 前半のまとめ

拡張機能(extension)は、PostgreSQLに「新しいデータ型・関数・インデックス方式などの“機能パック”を後付けする仕組み」であり、サーバ側にモジュールを入れたうえで、各データベースごとに CREATE EXTENSION を実行することで「このDBでこの拡張を使う」と宣言する。
PostGISはその代表例として、geometry/geography 型や空間関数(ST_MakePoint, ST_DWithin など)を提供し、「店舗の位置を geometry(Point, 4326) で持ち、ある地点から半径1km以内の店舗をSQLで検索する」といった“地理情報の専門知識”をDB側にインストールして使えるようにしてくれる一方、拡張に依存するということは「運用・セキュリティ・将来の移行もその拡張前提になる」という意味でもある――ここまでの構造とイメージが掴めていれば、Day27 前半としてはとても良いスタートラインです。

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