Supabase Postgres プロジェクト作成Database backbone
松葉 / Matsuba のデータベース(DB = データ保存の本体)には Supabase の Postgres を採用しました。Supabase は Postgres をマネージド(運用代行)で提供する SaaS で、Google Cloud と同じ 東京リージョンに Pro プラン(月額 $25〜)で配置しています。Auth(認証機能)は Supabase 標準ではなく Better Auth(後述)で独自管理する方針です。
採用ポイントWhy Supabase Pro
| 項目 | 本構築での値 | なぜそうしたか |
|---|---|---|
| プロジェクト名 | matsuba | 1 環境運用のため接尾辞なし |
| リージョン | Northeast Asia (Tokyo) | 個人情報保護法への配慮、Cloud Run(東京)との低レイテンシ |
| プラン | Pro(月額 $25〜) | Daily Backup + PITR を担保するため Free 不可 |
| Daily Backup | 一定期間分を自動取得 | Pro プラン標準 |
| PITR(任意時点に巻き戻せる機能) | 一定期間さかのぼれる | RPO の目標(最悪でも一定時間前の状態に戻せる)を担保 |
| Pool Size | 15(既定維持) | Cloud Run の同時接続数 × 接続プールから算出。実測で調整 |
kintone との対比: kintone では「テーブル設計=アプリ設計」で、SQL を直接書きません。Postgres は kintone より細かく型・制約・インデックス・暗号化を制御でき、20 年運用を見据えた監査ログのパーティション分割や行レベルセキュリティが実装できます。Auth を分離したのも、Supabase 標準では Better Auth の社内 SSO + 社外 OTP MFA 必須という二段構成が組めないためです。
接続経路 2 種Two connection strings
Postgres へは アプリ実行用とマイグレーション(DB 構造の変更適用)用で接続経路を分けています。接続経路をポート番号で使い分けるのが Supabase の流儀です。
2 経路に分ける理由: アプリは短時間に大量のクエリを投げるため、接続を束ねる Supavisor Pooler(ポート 6543)経由で接続効率を上げます。一方でマイグレーション(テーブル構造変更)は CREATE TABLE 等のセッション状態を要するため、プーラーを通さず Direct(ポート 5432)で接続する必要があります。
| 用途 | 接続文字列の保管先 | 使うのは誰 |
|---|---|---|
DATABASE_URL(アプリ用 / Supavisor 6543) | Secret Manager matsuba-database-url | Cloud Run(matsuba-api / matsuba-batch) |
DIRECT_URL(移行用 / Direct 5432) | GitHub Secrets PROD_DIRECT_URL | GitHub Actions(CI/CD でマイグレーション適用) |
有効化した Postgres 拡張Enabled extensions
Postgres は「拡張機能」で標準にない機能を取り込めます。Box 内検索の高速化、UUID(識別子)生成、ハッシュ計算のために 3 種類を ON にしました。
| 拡張 | 用途 | 用語の補足 |
|---|---|---|
pg_trgm | Box 内ファイル名のあいまい検索(部分一致 ILIKE)の高速化 | 「三文字組」で類似度を測る索引技術 |
uuid-ossp | UUID(ユニバーサル一意識別子、全世界で重複しない ID)の生成 | 「連番」より衝突に強く、分散環境向き |
pgcrypto | パスワードハッシュ等の暗号関数 | Better Auth が内部で利用 |
個人情報暗号化用の pgsodium は本手順では有効化しません。本手順では DB の基本機能のみを整え、暗号化は別の拡張作業として分離しています。
バックアップと災害復旧(DR)Backup & PITR
Daily Backup: Supabase が毎日自動取得し、一定期間分を保持。誤って DROP TABLE 等を流してしまった場合は前日に戻せます。
PITR (Point-in-Time Recovery): WAL(Postgres の変更履歴)を一定期間さかのぼれます。「2 時間前の状態に戻す」のような秒単位の復旧ができます。RPO(最悪のデータ損失幅)は目標を定めた範囲で担保しています。