PostgreSQL: PostgreSQLデータベースの作成と管理
最終更新:2026-08-26
データベースはPostgreSQLの最上位の組織単位であり、多くの引き出し(テーブル)を収納できるファイルキャビネットのようなものです。
1. 学習内容
- CREATE DATABASEによるデータベースの作成
- DROP DATABASEによるデータベースの削除
- ALTER DATABASEによるデータベースプロパティの変更
- テンプレートデータベース(template0 / template1)
- 文字セットと照合順序
- psqlメタコマンド:\l / \c
2. DevOpsエンジニアの実体験
(1) 悩み:3つの環境、3つの文字セット
CharlieはEコマースプロジェクト用に、dev / staging / prod環境に対応する3つのデータベースを作成する必要があります:
- dev:英語照合順序(開発に便利)
- staging:UTF8+英語照合順序(本番と一致)
- prod:UTF8+特定の照合順序(中東市場、アラビア語サポートが必要)
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) 得られた成果
- 各環境が独立したデータベースを持ち、データが干渉しない
- 文字セットがUTF8に統一され、多言語データをサポート
- 照合順序がビジネスニーズに一致し、クエリ結果の順序が正しい
3. データベースの基礎
(1) PostgreSQLの組織階層
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インスタンスを使用してください。
📖 まとめ
- CREATE DATABASEはデータベースを作成し、エンコーディング/照合順序/テンプレート/所有者/接続制限をサポート
- template0はクリーンなテンプレート(変更不可)、template1はカスタマイズ可能なテンプレート(デフォルト)
- template1に拡張をインストールすると、新しいデータベースに自動的に継承される
- ALTER DATABASEは名前変更、パラメータ設定、所有者変更が可能
- DROP DATABASEは元に戻せない、IF EXISTSでエラー防止、WITH (FORCE)で強制切断
- 常にUTF8エンコーディングを使用し、照合順序はビジネスニーズに基づいて選択
- psqlメタコマンド:
\lはデータベース一覧、\cはデータベース切り替え、\conninfoは接続情報表示
📝 練習問題
-
基礎(★): UTF8エンコーディングで
my_bookstoreという名前のデータベースを作成し、\lで作成を確認し、最後に削除してください。 -
中級(★★): まずtemplate1に
uuid-ossp拡張をインストールし、次に新しいデータベースtest_templateを作成して、新しいデータベースがuuid-ossp拡張を自動的に継承したことを確認してください。 -
発展(★★★):
C照合順序とen_US.utf8照合順序でそれぞれ2つのデータベースを作成してください。各データベースに同じテーブルを作成し、'apple'、'Banana'、'cherry'、'Apple'のデータを挿入し、ORDER BYを使用してソート結果を比較し、なぜ異なるのか説明してください。