自立編 2-02 / Essay
自立編 2-02 № 02 · 2026

まずデータ基盤を、
自分の手元に立てる。

すべてが乗るデータ基盤を、最初に自分の側に立てる

ビルダーの仕事は、コードを書くことから始まらない。実績ある OSS を立てることから始まる(1-05)。汎用的な機能は、もう世界で共有されている ── だから「書く」のではなく「立てる」。

全体像と対応表(2-01)に続いて、この自立編では、Microsoft 365 と Google Workspace、そして基幹のベンダー製品を置き換える OSS を、一つずつ実際に立てていく。最初に据えるのは データ基盤だ。分析も、AI の RAG も、講座の予約も、基幹システムも ── データは、すべてこの上に乗る。だから最初に据える。そして、普通は SQLite で十分だ ── 重い倉庫から始めなくていい。

なぜ土台(データ)から始めるのか

順番には理由がある。後の章で立てるものの多くが、データベースに依存する:

土台が先にあれば、上に立つものは「すでにある DB に乗せる」だけになる。 先に据えるほど、後が軽い

そして、その土台は最初から重くしなくていい。

普通は SQLite で十分だ。共有して複数人で書くときだけ、PostgreSQL に上げる

一人で、一つのアプリで、たいていの用途なら ── まず SQLite から始める。据える順番もこれに従う。

単一ファイルで持つ ── SQLite

データベースの既定は SQLite だ。サーバを立てず、一つのファイルに収まる。Python に最初から入っていて、追加のインストールも要らない。世界で最も多く使われているデータベースで ── スマホにもブラウザにも入っている。

# ライブラリも不要 ── 標準で入っている
sqlite3 app.db 'CREATE TABLE memo(id integer primary key, body text)'

一人で持つ設定も、端末の手元の小さなデータも、これで足りる。次章で立てる 門番(PocketBase)も、この SQLite の上で動く一つのアプリが手元で持つだけなら、まず SQLite。標準 SQL なので、Claude がそのまま書く。

足りなくなるのは、共有して複数人が同時に書くときだ。そのときだけ、倉庫を一段上げる。

共有・複数人で書くなら PostgreSQL

複数のアプリや人が同時に読み書きする共有の倉庫が要るなら、PostgreSQL に上げる。オープンソース、無料、商用可。Oracle や SQL Server と同等以上の機能を持ち、Claude が最も得意とする方言だ(1-05・2-01)。 SQLite と同じ標準 SQL だから、上げても書き方は変わらない。手帳(SQLite) から倉庫(PostgreSQL)へ、用途で持ち替える

compose.yaml 一枚で立つ。

# compose.yaml ── PostgreSQL + pgvector 同梱イメージ
services:
  db:
    image: pgvector/pgvector:pg17
    environment:
      POSTGRES_PASSWORD: change-me
      POSTGRES_DB: app
    ports: ["5432:5432"]
    volumes: ["./pgdata:/var/lib/postgresql/data"]
    restart: always
docker compose up -d            # 起動
docker compose exec db psql -U postgres -d app -c '\l'   # 接続確認

pgvector/pgvector イメージを使うと、後で要る ベクトル拡張が最初から入っている。素の postgres イメージでも動くが、その場合は拡張を別途入れる(次節)。

pgvector を有効化する

AI の RAG(自立編の後の章)で使う ベクトル検索を、いま有効にしておく。拡張を一行で足すだけだ。

-- データベースに一度だけ実行
CREATE EXTENSION IF NOT EXISTS vector;

-- 埋め込みを持つテーブルの例(1024 次元は bge-m3 の例)
CREATE TABLE docs (
  id    bigserial PRIMARY KEY,
  body  text,
  embedding vector(1024)
);

これで、文書を「意味」で検索する土台ができた。embedding に埋め込みを入れ、ORDER BY embedding <=> :query で近いものを引く ── 実際の RAG パイプラインは AI の章で組む。いまは器だけ用意しておく

Azure SQL から移す

既存の Azure SQL / SQL Server がある場合は、pgloader がスキーマもデータも一括で運ぶ。

pgloader mssql://user:pass@azure-host/db \
         postgresql://postgres:change-me@localhost/app

標準 SQL(SELECTJOIN・ウィンドウ関数)はそのまま動く。捨てるのは ベンダー方言の T-SQL だけだ。ストアドに埋まった業務ロジックは、 Claude が抽出して Python / Ruby に翻訳する(1-05)。あとは旧 DB と並行稼働で出力を突き合わせ、差分が消えたら旧を止める(2-09)。

移行は「全部を書き直す」ことではない。 標準に乗せ替え、方言だけ捨てる ことだ。

DuckDB で分析する ── Excel と Power BI を大差で抜く

集計・分析は、PostgreSQL の上に DuckDB を重ねる。列指向(カラムナ)の分析エンジンで、1 ファイル、サーバー不要。Excel が約 104 万行で頭打ちなのに対し、ノート PC 一台で数億行を秒で集計する

pip install duckdb polars       # これだけ
import duckdb
# Parquet も PostgreSQL も CSV も、その場で SQL で串刺し集計
duckdb.sql("INSTALL postgres; LOAD postgres;")
duckdb.sql("ATTACH 'dbname=app user=postgres host=localhost' AS pg (TYPE postgres)")
duckdb.sql("SELECT 部門, sum(売上) FROM pg.sales GROUP BY 部門 ORDER BY 2 DESC")

データを移し替えず、置いた場所のまま 分析できる。SQL は Claude が書く ── 「先月比で異常な部門は」を、手元の実データに対して、追加料金ゼロで何度でも問える。Power BI のクラウド従量・人数課金から見れば、これは別次元だ。

Excel データを扱う ── Polars

Excel は、人が数字を入れ、人が結果を読む 入出力の道具だ。その役割は変わらない ── だから次章では Excel 互換の OnlyOffice を自分の側に立てる。変わるのは、その裏でデータを捌く側だ。

手元に積み上がった .xlsx は、Polars がそのまま読む。Rust 製の高速データフレームで、Excel が固まる行数でも瞬時に処理し、結果を Excel・ PostgreSQL・Parquet のどれにでも書き戻す。

import polars as pl
df  = pl.read_excel("売上_2025.xlsx")                # 人が作った Excel を読む
agg = df.group_by("部門").agg(pl.col("売上").sum())  # 重い集計は一行
agg.write_excel("部門集計.xlsx")                      # 人が読む Excel に書き戻す

人は Excel で入れて読み、機械は Polars と DuckDB で捌く。人の道具と機械の道具を、役割で分ける。SQL で書きたい処理は DuckDB、データフレームで捏ねたい処理は Polars ── 同じデータを、好きな道具で触れる。

巨大データを常時集計するなら、列指向 DB サーバーの ClickHouse に載せ替える。だが大半の社内分析は、DuckDB と Polars で足りる。

まとめ

データ基盤を、最初に自分の側へ。

書いたコードは、ほとんど無い。汎用は、すでに OSS として在る。ビルダーは、それを立てる。次章では、その上に 認証(PocketBase) を据え、アプリ共通の門番にする。


関連記事