PostgreSQLのセットアップ方法、どれを選ぶべき?
PostgreSQLを始めるには、最初のクエリを書く前に選択が必要です。主な方法は3つ——OSにネイティブインストールする、Dockerで動かす、Amazon RDSやSupabaseのようなマネージドクラウドサービスを使う。どれを選んでも取り返しのつかない失敗にはなりませんが、学習中に余計な摩擦が生じることがあります。
3つのアプローチの違いを整理すると:
- ネイティブインストール — PostgreSQLをマシンに直接インストール(Linux、macOS、Windows)。学習やローカル開発に最適。
- Docker — コンテナでPostgreSQLを動かす。全員が同じ環境を必要とするチームプロジェクトに向いている。
- マネージドクラウドサービス — AWS RDS、Google Cloud SQL、Supabaseなど。サーバー管理を自分でやりたくない本番環境に適した選択。
各アプローチのメリット・デメリット
ネイティブインストール
- メリット:シンプル、直接アクセス可能、オーバーヘッドなし、最も学習しやすい。
- デメリット:インストール済みの他のバージョンと競合する可能性がある、マシン間での再現が難しい、手動アップグレードが必要。
Docker
- メリット:隔離された環境、リセットが簡単、開発マシン間で再現可能、バージョン固定ができる。
- デメリット:Dockerの知識が必要、わずかなオーバーヘッド、データ永続化には明示的なボリューム設定が必要。
マネージドクラウドサービス
- メリット:自動バックアップ、高可用性、インフラ管理不要。
- デメリット:費用がかかる(AWS RDSは最小インスタンスで月$15〜25程度から)、ローカル開発時にネットワーク遅延が発生、設定の自由度が低い。
学習に推奨するセットアップ
PostgreSQL初心者なら、Ubuntu/DebianへのネイティブインストールかDockerをこの순序で検討してください。初心者にはネイティブが有利です——コンテナの抽象化レイヤーを挟まず、データベースと直接やり取りできるからです。
私はUbuntu上でネイティブのPostgreSQLを本番環境で3年以上動かしてきました。安定していて予測可能、予期しない問題もありません。直接インストールすることで、データベースの実際の動作——データファイルの場所(/var/lib/postgresql/)、サービスの起動方法、ログの保存先——をコンテナやクラウドの裏側に隠す前に理解できます。
基礎をしっかり固めたら、実際のチームプロジェクトではDockerの方が優れた選択肢になります。
実装ガイド
ステップ1:Ubuntu/DebianへのPostgreSQLインストール
ターミナルを開き、以下のコマンドを実行します:
# パッケージリストを更新
sudo apt update
# PostgreSQLをインストール
sudo apt install -y postgresql postgresql-contrib
# 起動しているか確認
sudo systemctl status postgresql
出力に active (running) と表示されているはずです。PostgreSQLはインストール時に postgres というデフォルトのシステムユーザーも自動的に作成します。
ステップ2:PostgreSQLシェルにアクセス
postgres システムユーザーに切り替えてから、インタラクティブシェルを開きます:
# postgresユーザーに切り替え
sudo -i -u postgres
# psqlシェルを開く
psql
これで psql プロンプトの中に入りました:
postgres=#
頻繁に使う4つのメタコマンド:
\l— 全データベースを一覧表示\c dbname— データベースに接続\dt— 現在のデータベースのテーブルを一覧表示\q— 終了
ステップ3:データベースとユーザーの作成
postgres スーパーユーザーは簡単なテストには問題ありませんが、実際のプロジェクトには専用のデータベースとユーザーを用意すべきです——ローカルであっても:
-- 新しいデータベースを作成
CREATE DATABASE myapp;
-- パスワード付きで新しいユーザーを作成
CREATE USER appuser WITH PASSWORD 'securepassword';
-- そのユーザーにデータベースの全権限を付与
GRANT ALL PRIVILEGES ON DATABASE myapp TO appuser;
次に接続します:
\c myapp
ステップ4:最初のテーブルを作成
練習用のシンプルな users テーブル:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
各部分の意味:
SERIAL— 自動インクリメントの整数。PostgreSQLがIDを自動生成します。PRIMARY KEY— 各行を一意に識別します。NOT NULL— そのカラムを空にできません。DEFAULT CURRENT_TIMESTAMP— 挿入時に現在時刻を自動で設定します。
ステップ5:基本的なCRUD操作
CRUD——Create(作成)、Read(読み取り)、Update(更新)、Delete(削除)。4つの操作です。どんなプロジェクトでも必ず使います。
INSERT — データの追加
INSERT INTO users (username, email) VALUES
('alice', '[email protected]'),
('bob', '[email protected]'),
('charlie', '[email protected]');
SELECT — データの読み取り
-- 全ユーザーを取得
SELECT * FROM users;
-- 特定のカラムを取得
SELECT username, email FROM users;
-- WHEREで絞り込み
SELECT * FROM users WHERE username = 'alice';
-- 結果を並び替え
SELECT * FROM users ORDER BY created_at DESC;
-- 件数を制限
SELECT * FROM users LIMIT 10;
UPDATE — データの更新
-- 特定ユーザーのメールアドレスを更新
UPDATE users
SET email = '[email protected]'
WHERE username = 'alice';
-- UPDATEには必ずWHEREを使うこと。そうしないと全行が更新されてしまう
DELETE — データの削除
-- 特定ユーザーを削除
DELETE FROM users WHERE username = 'charlie';
-- 同様に:必ずWHEREを使うこと。そうしないとテーブル全体が消える
ステップ6:Pythonから接続する
実際には、psqlにSQLを直接入力することはほとんどありません。アプリのコードから実行します。Pythonの psycopg2 ライブラリを使った方法を紹介します:
pip install psycopg2-binary
import psycopg2
# PostgreSQLに接続
conn = psycopg2.connect(
host="localhost",
database="myapp",
user="appuser",
password="securepassword"
)
cursor = conn.cursor()
# 新しいユーザーを挿入
cursor.execute(
"INSERT INTO users (username, email) VALUES (%s, %s)",
("david", "[email protected]")
)
conn.commit()
# 全ユーザーを取得
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:
print(row)
# 必ず接続を閉じること
cursor.close()
conn.close()
%s プレースホルダーが見えますか?これをPythonの文字列フォーマットに置き換えてはいけません。%s 構文によってpsycopg2がエスケープ処理を行います——これがSQLインジェクションを防ぐ仕組みです。文字列結合でクエリを組み立てると、悪意のある入力一つでデータベース全体が消える可能性があります。
ステップ7:実践的なヒント集
- トランザクションを使う:関連する操作を
BEGIN/COMMITでまとめましょう。一つのステップが失敗すれば、どれも適用されません——金銭処理や関連レコードを扱う際に不可欠です。 - 絞り込みに使うカラムにインデックスを張る:
CREATE INDEX idx_users_email ON users(email);— 100万行のテーブルでは、適切なインデックスによりメールアドレスでのフィルタリングが約800msから5ms未満に短縮できます。 - クエリプランを読む:クエリの前に
EXPLAIN ANALYZEを付けると、PostgreSQLがどのように実行するかが詳しくわかります。本番環境に出す前に遅いクエリを診断するのに非常に役立ちます。 - 定期的にバックアップを取る:
pg_dump myapp > backup.sqlでデータベースをエクスポートできます。psql myapp < backup.sqlでリストアできます。シンプルで確実な方法です。
次のステップ
上記の基礎だけでも意外と遠くまで行けます。限界を感じ始めたら、JOIN(1つのクエリで複数テーブルの関連データを取得する)、より深いインデックス戦略、トランザクション管理に取り組みましょう。
その先は、本番環境向けに pgBouncer によるコネクションプーリングとレプリケーションです。postgresql.org/docs の公式PostgreSQLドキュメントは本当に優れています——詳細で正確、よく整理されています。最初の日からブックマークしておきましょう。

