PostgreSQL: PostgreSQLデータベースの作成と管理

最終更新:2026-08-26

データベースはPostgreSQLの最上位の組織単位であり、多くの引き出し(テーブル)を収納できるファイルキャビネットのようなものです。

1. 学習内容


2. DevOpsエンジニアの実体験

(1) 悩み:3つの環境、3つの文字セット

CharlieはEコマースプロジェクト用に、dev / staging / prod環境に対応する3つのデータベースを作成する必要があります:

Charlieはデータベース作成時に文字セットと照合順序を指定する方法がわからず、テンプレートデータ��ースが何かも知りません。

(2) CREATE DATABASEによる解決

PostgreSQLのCREATE DATABASEでは、作成時に文字セット、照合順序、テンプレートを指定できます:

SQL
-- 環境ごとに異なるロケールでデータベースを作成
CREATE DATABASE shop_dev
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    TEMPLATE = template1;

CREATE DATABASE shop_staging
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8';

CREATE DATABASE shop_prod
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8';

(3) 得られた成果


3. データベースの基礎

(1) PostgreSQLの組織階層

100%
graph TB
    PG[PostgreSQLインスタンス<br/>1つの実行中サーバー] --> DB1[データベース: shop_dev]
    PG --> DB2[データベース: shop_staging]
    PG --> DB3[データベース: shop_prod]
    DB1 --> SC1[スキーマ: public]
    SC1 --> T1[テーブル: users]
    SC1 --> T2[テーブル: orders]
    DB2 --> SC2[スキーマ: public]
    DB3 --> SC3[スキーマ: public]
レベル 説明
インスタンス 1つの実行中のPostgreSQLサーバープロセス 1インスタンスに多数のデータベース
データベース 最上位の独立した名前空間 1データベースに多数のスキーマ
スキーマ データベース内の名前空間(デフォルトはpublic) 1スキーマに多数のテーブル
テーブル データを格納する2次元テーブル テーブルはスキーマに属する
💡 ヒント: MySQLとは異なり、PostgreSQLの「データベース」はMySQLの「スキーマ」に近い概念です。PGでは接続時にデー▶ベースを指定する必要があり、データベースを跨いで直接JOINすることはできません(クロスデータベースクエリにはFDWが必要で、後続のレッスンで扱います)。


4. CREATE DATABASE

(1) 基本構文

SQL
CREATE DATABASE name
    [WITH]
    [OWNER = user_name]
    [TEMPLATE = template]
    [ENCODING = encoding_name]
    [LC_COLLATE = lc_collate]
    [LC_CTYPE = lc_ctype]
    [TABLESPACE = tablespace_name]
    [CONNECTION LIMIT = conn_limit]
    [IS_TEMPLATE = true | false];
パラメータ デフォルト 説明
OWNER 実行ユーザー データベースの所有者
TEMPLATE template1 新しいデータベース作成時にコピーされるテンプレート
ENCODING テンプレートのエンコーディング 文字エンコーディング(UTF8推奨)
LC_COLLATE テンプレートの照合順序 文字列のソート順序
LC_CTYPE テンプレートの文字分類 文字分類(大文字小文字/数字など)
TABLESPACE デフォルトテーブルスペース データファイルの保存場所
CONNECTION LIMIT -1(無制限) 最大同時接続数
IS_TEMPLATE false テンプレートデータベースとしてマーク

▶ サンプル:基本的なデータベー��の作成

SQL
-- デフォルト設定でシンプルなデータベースを作成
CREATE DATABASE my_app;

-- 作成を確認
\l

Output:

TEXT 📖 参照専用
CREATE TABLE

▶ サンプル:全パラメータを指定したデータベースの作成

SQL
-- すべての一般的なオプションを指定してデータベースを作成
CREATE DATABASE shop_prod
    WITH OWNER = devuser
    ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    CONNECTION LIMIT = 100;

Output:

TEXT 📖 参照専用
CREATE TABLE
⚠️ 注意: CREATE DATABASEはトランザクション内で実行できません(BEGIN...COMMIT内で実行するとエラーになります)。これはPGの設計上の仕様で、データベースの作成はDDL操作でありロールバックできません。


5. テンプレートデータベース

(1) template0 vs template1

PostgreSQLには2つの組み込みテンプレートデータベースが付属しています:

プロパティ template0 template1
目的 変更不可のクリーンなテンプレート カスタマイズ可能なテンプレート
変更可能? ❌ 不可 ✅ 可
デフォルト内容 最小限のシステムオブジェクト template0と同じ+ユーザー定義オブジェクト
使用する場面 元のエンコーディング/照合順序を復元する必要がある場合 日常的なデータベース作成(デフォルト)
作成方法 TEMPLATE = template0 TEMPLATE = template1(デフォルト)
📌 ポイント: template1にテーブル、関数、拡張を一度作成すると、以降のすべての新しいデータベースがそれらのオブジェクト��継承します。これは新しいデータベースを事前設定する便利な方法です。

▶ サンプル:テンプレートでデータベースを事前設定

SQL
-- ステップ1: template1に接続して共通の拡張を追加
\c template1

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

-- ステップ2: これで新しいデータベースはすべ��これらの拡張を持つ
\c postgres

CREATE DATABASE new_project;
-- new_projectは自動的にuuid-osspとpg_trgmを持つ

-- ステップ3: 確認
\c new_project
\dx

Output:

TEXT 📖 参照専用
CREATE TABLE

▶ サンプル:template0でエンコーディングを再構築

SQL
-- template1が必要なエンコーディングと異なる場合、
-- template0を使用して特定のエンコーディングでデータベースを作成
CREATE DATABASE db_with_latin
    TEMPLATE = template0
    ENCODING = 'LATIN1'
    LC_COLLATE = 'C'
    LC_CTYPE = 'C';

Output:

TEXT 📖 参照専用
CREATE TABLE

6. ALTER DATABASE

(1) 一般的な変更

操作 構文 説明
名前変更 ALTER DATABASE old_name RENAME TO new_name データベース名の変更
パラメータ設定 ALTER DATABASE name SET parameter = value データベースのランタイムパラメータを設定
パラメータリセット ALTER DATABASE name RESET parameter パラメータのデフォルトを復元
所有者変更 ALTER DATABASE name OWNER TO new_owner データベース所有者の変更
接続制限設定 ALTER DATABASE name CONNECTION LIMIT = n 最大接続数の変更
テンプレートマーク ALTER DATABASE name IS_TEMPLATE = true テンプレートとしてマーク/解除

▶ サンプル:データベースプロパティの変更

SQL
-- データベース名の変更(先に全ユーザーを切断する必要あり)
ALTER DATABASE shop_dev RENAME TO shop_development;

-- データベースのデフォルトsearch_pathを設定
ALTER DATABASE shop_prod SET search_path TO public, admin;

-- 特定のデータベースにwork_memを設定
ALTER DATABASE shop_prod SET work_mem = '64MB';

-- 接続制限の変更
ALTER DATABASE shop_prod CONNECTION LIMIT = 200;

-- テンプレートとしてマーク
ALTER DATABASE shop_base IS_TEMPLATE = true;

Output:

TEXT 📖 参照専用
-- SQL文が正常に実行されました
⚠️ 注意: データベース名を変更する前に、接続しているすべてのユーザーを切断する必要があります。次のクエリでアクティブな接続を確認でき▶す:

SQL
-- データベースへのアクティブな接続を検索
SELECT pid, usename, application_name, client_addr, state
FROM pg_stat_activity
WHERE datname = 'shop_dev';

7. DROP DATABASE

(1) 削除構文

SQL
DROP DATABASE [IF EXISTS] name [WITH (FORCE)];
オプション 説明
IF EXISTS データベースが存在しなくてもエラーにしない(通知のみ)
WITH (FORCE) 全接続を強制切断してから削除(PG 13+)

▶ サンプル:データベースの削除

SQL
-- 安全な削除(データベースが存在しなくてもエラーにしない)
DROP DATABASE IF EXISTS old_project;

-- 強制削除(先に全ユーザーを切断、PG 13+)
DROP DATABASE IF EXISTS shop_dev WITH (FORCE);

Output:

TEXT 📖 参照専用
-- SQL文が正常に実行されました
🔥 要注意: データベースの削除は元に戻せません!データベース内のすべてのテーブル、データ、ビューが永久に失われます。本番環境では、削除前に必ずバックアップを取ってください。


8. 文字セットと照合順序

(1) 一般的な文字エンコーディング

エンコーディング 説明 推奨シナリオ
UTF8 Unicode、全言語をサポート すべてのプロジェクト(推奨)
LATIN1 西ヨーロッパ言語 レガシーシステム互換性
EUC_JP 日本語 レガシー日本語システム
SQL_ASCII エンコーディング変換なし 純粋なASCIIデータ

(2) 照合順序の比較

照合順序 動作
en_US.utf8 英語ソート、大文字小文字区別あり A, a, B, b
C バイト順ソート、最速 A, B, a, b
en_US.utf8(ICU使用) より柔軟なソート 大文字小文字/アクセントを無視可能

▶ サンプル:システムがサポートするエンコーディングと照合順序を表示

SQL
-- 利用可能なエンコーディングを一覧表示
SELECT name, description FROM pg_encodings LIMIT 10;

-- 利用可能な照合順序を一覧表示
SELECT name, locale FROM pg_collation LIMIT 10;

Output:

TEXT 📖 参照専用
 id | name     | value 
----+----------+-------
  1 | example  | 42
(1 row)

▶ サンプル:照合順序がクエリ結果に与える影響

SQL
-- テストテーブルにテキストデータを作成
CREATE TABLE sort_test (name TEXT);
INSERT INTO sort_test VALUES ('apple'), ('Banana'), ('cherry'), ('Apple');

-- Cロケールでソート(バイト順:大文字が先)
SELECT name FROM sort_test ORDER BY name COLLATE "C";

-- en_US.utf8でソート(辞書順:同じ文字内で大文字小文字を区別しない)
SELECT name FROM sort_test ORDER BY name COLLATE "en_US.utf8";

-- クリーンアップ
DROP TABLE sort_test;

Output:

TEXT 📖 参照専用
-- Cロケール:
  Apple
  Banana
  apple
  cherry

-- en_US.utf8:
  apple
  Apple
  Banana
  cherry

9. psqlデータベース管理メタコマンド

コマンド 同等のSQL 説明
\l SELECT * FROM pg_database 全データベースを一覧表示
\l+ 同上、テーブルスペース/サイズ付き データベースを詳細表示
\c dbname - 指定データベースに切り替え
\conninfo - 現在の接続情報を表示

▶ サンプル:psqlでのデータベース管理

BASH
# 全データベースを一覧表示
\l

# shop_devデータベースに切り替え
\c shop_dev

# 現在の接続を確認
\conninfo

# postgresデータベースに戻る
\c postgres

Output:

TEXT 📖 参照専用
# コマンドが正常に実行されました

10. 完全な例:3環境データベースのセットアップ

SQL
-- ============================================
-- 完全な例:Eコマースプロジェクト用に
-- dev/staging/prodデータベースをセットアップ
-- ============================================

-- ステップ1: postgresに接続(メンテナンス用データベース)
\c postgres

-- ステップ2: 英語ロケールでdevデータベースを作成
CREATE DATABASE shop_dev
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 50;

-- ステップ3: stagingデータベースを作成(prodと同じ設定)
CREATE DATABASE shop_staging
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 50;

-- ステップ4: 接続制限付きでprodデータベースを作成
CREATE DATABASE shop_prod
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 200;

-- ステップ5: prodにデフォルトsearch_pathを設定
ALTER DATABASE shop_prod SET search_path TO public, admin;

-- ステップ6: すべてのデータベー��の作成を確認
SELECT datname, pg_encoding_to_char(encoding) AS encoding,
       datcollate, datctype, datconnlimit
FROM pg_database
WHERE datname LIKE 'shop_%'
ORDER BY datname;

Output:

TEXT 📖 参照専用
   datname    | encoding |  datcollate  |   datctype   | datconnlimit
--------------+----------+--------------+--------------+-------------
 shop_dev     | UTF8     | en_US.utf8   | en_US.utf8   |           50
 shop_prod    | UTF8     | en_US.utf8   | en_US.utf8   |          200
 shop_staging | UTF8     | en_US.utf8   | en_US.utf8   |           50

❓ よくある質問

Q PostgreSQLインスタンスが作成できるデータベースの最大数は?
A 理論上はハードリミットはありませんが、各データベースはシステムカタログのスペースを消費します。実用的には、単一インスタンスで100データベース未満に抑えてください。より多くの分離が必要な場合は、代わりにスキーマの使用を検討してください。
Q CREATE DATABASEが「source データベース is being accessed by other users」というエラーを出す場合は?
A template1が別の接続で使用されていることを意味します。解決策:1) template1に接続している全セッションを終了する、または2) 代わりに TEMPLATE = template0 を使用してください。
Q LC_COLLATEとLC_CTYPEの違いは何ですか?
A LC_COLLATEは文字列のソート順序(ORDER BYの結果)を制御し、LC_CTYPEは文字分類(大文字小文字変換、文字と見なされるものなど)を制御します。ほとんどの場合、両方を同じに設定すれば問題ありません。
Q データベース作成後に文字エンコーディングを変更できますか?
A 直接は変更できません。データをpg_dumpし、新しいエンコーディングで新しいデータベースを作成し、pg_restoreする必要があります。そのため最初からUTF8を推奨しています。すべての言語をサポートするからです。
Q 現在のデータベースのサイズを確認するには?
A 単一データベースには SELECT pg_size_pretty(pg_database_size('shop_dev')) を使用し、全データベースサイズを確認するには \l+ を使用してください。
Q devとprodで1つのデータベースを共有できますか?
A 強く非推奨です。開発中の操作(DROP TABLE、一括DELETE)が誤って本番データを破壊する可能性があります。最低限の要件:devとprodは異なるデータベースを使用し、できれば異なるPGインスタンスを使用してください。

📖 まとめ


📝 練習問題

  1. 基礎(★): UTF8エンコーディングで my_bookstore という名前のデータベースを作成し、\l で作成を確認し、最後に削除してください。

  2. 中級(★★): まずtemplate1に uuid-ossp 拡張をインストールし、次に新しいデータベース test_template を作成して、新しいデータベースがuuid-ossp拡張を自動的に継承したことを確認してください。

  3. 発展(★★★): C 照合順序と en_US.utf8 照合順序でそれぞれ2つのデータベースを作成してください。各データベースに同じテーブルを作成し、'apple''Banana''cherry''Apple' のデータを挿入し、ORDER BYを使用してソート結果を比較し、なぜ異なるのか説明してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%