PostgreSQLスキーマ作成・削除完全ガイド!初心者でもわかるデータベース設計の基礎
生徒
「PostgreSQLでスキーマって言葉を聞いたんですけど、これって何ですか?」
先生
「スキーマは、データベースの中をさらに区切るための仕組みです。大きな本棚の中に、ジャンル別の仕切りを作るようなものですね。」
生徒
「データベースだけじゃダメなんですか?なぜスキーマが必要なんでしょう?」
先生
「データベースが会社の建物だとすれば、スキーマは各部署のようなものです。営業部、経理部、人事部と分けることで、データを整理しやすくなります。」
PostgreSQLのスキーマとは何か?
スキーマとは、データベース内でテーブルやビュー、関数などのオブジェクトをグループ化して管理するための名前空間のことです。名前空間という言葉は難しく聞こえますが、要するに「名前が重複しないように区切られた領域」という意味です。
例えば、会社のシステムを考えてみましょう。営業部門にも経理部門にも「売上」というテーブルが必要かもしれません。スキーマを使わないと、同じデータベース内に同じ名前のテーブルを二つ作ることはできません。しかし、「営業スキーマ」と「経理スキーマ」を作れば、それぞれに「売上」テーブルを持つことができます。
PostgreSQLでは、データベースを作成すると、デフォルトで「public」という名前のスキーマが自動的に作成されます。何も指定しない場合、テーブルなどはこのpublicスキーマに作成されます。つまり、今までスキーマを意識していなくても、実は自動的にpublicスキーマを使っていたのです。
スキーマを使うメリットと活用場面
スキーマを使うことで、データベース管理に様々なメリットが生まれます。実際の運用でどのように活用されるのか見ていきましょう。
データの論理的な整理
大規模なシステムでは、数百個ものテーブルが存在することがあります。これらすべてを一つのスキーマにまとめると、管理が非常に困難になります。スキーマで分類することで、どこに何があるか分かりやすくなります。
例えば、ショッピングサイトのデータベースなら、「商品管理用スキーマ」「顧客管理用スキーマ」「注文管理用スキーマ」のように分けることができます。
セキュリティとアクセス制御
スキーマ単位で権限を設定できるため、セキュリティ管理が簡単になります。営業部のユーザーには営業スキーマへのアクセスだけを許可し、給与情報を含む人事スキーマへのアクセスは人事部だけに制限する、といった制御が可能です。
複数チームでの開発
大きなプロジェクトでは、複数のチームが同時に開発を進めることがあります。各チームに専用のスキーマを割り当てることで、お互いのテーブル名が衝突する心配がなくなります。開発スキーマとテストスキーマを分けて、本番に影響を与えずに開発を進めることもできます。
基本的なスキーマ作成方法
それでは、実際にスキーマを作成してみましょう。スキーマの作成はCREATE SCHEMAコマンドを使います。構文は非常にシンプルです。
CREATE SCHEMA sales;
このコマンドで、「sales」という名前のスキーマが作成されます。CREATE SCHEMAの後ろに、作成したいスキーマの名前を指定するだけです。
スキーマ作成の確認方法
スキーマが正しく作成されたか確認するには、psqlコマンドラインツールで「\dn」というコマンドを使います。これはデータベース内の全スキーマを一覧表示するコマンドです。
List of schemas
Name | Owner
---------+----------
public | postgres
sales | postgres
このように、デフォルトのpublicスキーマと、今作成したsalesスキーマが表示されます。Ownerの欄には、そのスキーマを作成したユーザー名が表示されます。
所有者を指定したスキーマ作成
スキーマを作成する際に、特定のユーザーを所有者として指定することもできます。所有者は、そのスキーマ内のオブジェクトを自由に操作できます。
CREATE SCHEMA accounting AUTHORIZATION accounting_user;
このコマンドは、「accounting」という名前のスキーマを作成し、その所有者を「accounting_user」に設定します。AUTHORIZATIONキーワードの後に、所有者にしたいユーザー名を指定します。
スキーマ内にテーブルを作成する方法
スキーマを作成したら、その中にテーブルを作ってみましょう。スキーマを指定してテーブルを作成するには、テーブル名の前にスキーマ名を付けます。
CREATE TABLE sales.customers (
customer_id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
registration_date DATE
);
この例では、salesスキーマの中に「customers」テーブルを作成しています。「sales.customers」のように、スキーマ名とテーブル名をドット(.)で繋いで指定します。これを「完全修飾名」といいます。
スキーマ内のテーブルにデータを挿入
作成したテーブルにデータを挿入する際も、同じように完全修飾名を使います。
INSERT INTO sales.customers (name, email, registration_date)
VALUES
('山田太郎', 'yamada@example.com', '2025-01-15'),
('佐藤花子', 'sato@example.com', '2025-01-16'),
('鈴木一郎', 'suzuki@example.com', '2025-01-17');
customer_id | name | email | registration_date
------------+------------+----------------------+------------------
1 | 山田太郎 | yamada@example.com | 2025-01-15
2 | 佐藤花子 | sato@example.com | 2025-01-16
3 | 鈴木一郎 | suzuki@example.com | 2025-01-17
スキーマ内のデータを検索
データを検索する際も、完全修飾名を使ってスキーマを指定します。
SELECT * FROM sales.customers WHERE registration_date >= '2025-01-16';
customer_id | name | email | registration_date
------------+------------+----------------------+------------------
2 | 佐藤花子 | sato@example.com | 2025-01-16
3 | 鈴木一郎 | suzuki@example.com | 2025-01-17
検索パスの設定と活用
毎回「スキーマ名.テーブル名」と入力するのは面倒です。そこで、検索パス(search_path)という機能を使って、デフォルトで使用するスキーマを設定できます。
現在の検索パスを確認
現在設定されている検索パスは、次のコマンドで確認できます。
SHOW search_path;
search_path
-----------------
"$user", public
デフォルトでは、ユーザー名と同じスキーマ、そしてpublicスキーマの順で検索されます。
検索パスの変更方法
検索パスを変更することで、スキーマ名を省略してテーブルにアクセスできるようになります。
SET search_path TO sales, public;
このコマンドを実行すると、まずsalesスキーマを検索し、見つからなければpublicスキーマを検索するようになります。これで「sales.customers」を単に「customers」と書くだけでアクセスできます。
セッション単位とユーザー単位の設定
SET search_pathで変更した設定は、現在のセッション(接続)でのみ有効です。接続を切ると元に戻ります。ユーザー単位で永続的に設定したい場合は、ALTER USERコマンドを使います。
ALTER USER sales_user SET search_path TO sales, public;
これで、sales_userでログインするたびに、自動的にsalesスキーマが優先的に検索されるようになります。
スキーマの削除方法
不要になったスキーマを削除するには、DROP SCHEMAコマンドを使います。ただし、削除には注意が必要です。
空のスキーマを削除
スキーマ内にテーブルなどのオブジェクトが何も存在しない場合は、単純にDROP SCHEMAコマンドで削除できます。
DROP SCHEMA sales;
このコマンドで、salesスキーマが削除されます。ただし、スキーマ内にテーブルやビューなどが残っている場合は、エラーになります。
オブジェクトごと削除
スキーマ内のテーブルなども含めて、すべてまとめて削除したい場合は、CASCADEオプションを使います。これは非常に強力なコマンドなので、実行前に十分確認してください。
DROP SCHEMA sales CASCADE;
CASCADEを付けると、スキーマ内のすべてのテーブル、ビュー、関数などが削除されます。データも完全に消えてしまうので、本番環境では特に慎重に実行してください。削除する前に、必ずバックアップを取ることをお勧めします。
安全な削除方法
IF EXISTSオプションを付けると、スキーマが存在しない場合でもエラーにならず、警告だけが表示されます。スクリプトで自動化する際に便利です。
DROP SCHEMA IF EXISTS temp_schema CASCADE;
このコマンドは、temp_schemaが存在すれば削除し、存在しなければ何もしません。エラーで処理が止まることがないため、安全です。
スキーマの名前変更とその他の操作
作成したスキーマの設定を後から変更することもできます。
スキーマ名の変更
スキーマの名前を変更するには、ALTER SCHEMAコマンドを使います。
ALTER SCHEMA sales RENAME TO sales_department;
このコマンドで、salesスキーマの名前がsales_departmentに変更されます。スキーマ内のテーブルはそのまま残り、アクセスする際は新しいスキーマ名を使います。
スキーマの所有者変更
スキーマの所有者を別のユーザーに変更することもできます。
ALTER SCHEMA accounting OWNER TO new_accounting_manager;
このコマンドで、accountingスキーマの所有者がnew_accounting_managerに変更されます。所有者には、そのスキーマ内のオブジェクトを管理する権限があります。
スキーマとアクセス権限の管理
スキーマには、ユーザーごとに異なるアクセス権限を設定できます。これにより、セキュアなデータベース運用が可能になります。
スキーマの使用権限を付与
他のユーザーにスキーマを使用させるには、USAGE権限を付与します。
GRANT USAGE ON SCHEMA sales TO sales_user;
USAGE権限を持つユーザーは、そのスキーマ内のオブジェクトにアクセスできるようになります。ただし、テーブルへのアクセス権限は別途必要です。
スキーマ内のオブジェクト作成権限
スキーマ内に新しいテーブルなどを作成する権限は、CREATE権限で管理します。
GRANT CREATE ON SCHEMA sales TO developer_user;
この権限を持つユーザーは、salesスキーマ内に自由にテーブルやビューを作成できます。
権限の取り消し
付与した権限を取り消すには、REVOKEコマンドを使います。
REVOKE CREATE ON SCHEMA sales FROM developer_user;
このコマンドで、developer_userからsalesスキーマ内でのオブジェクト作成権限が取り消されます。
実践的なスキーマ設計例
実際のプロジェクトでは、どのようにスキーマを設計すればよいのか、具体例を見ていきましょう。
部門別スキーマ構成
大企業のシステムでは、部門ごとにスキーマを分けると管理しやすくなります。
- sales:営業部門(顧客情報、商談履歴、売上データ)
- accounting:経理部門(会計データ、請求書、支払情報)
- hr:人事部門(社員情報、給与、勤怠データ)
- inventory:在庫管理部門(商品在庫、入出庫履歴)
環境別スキーマ構成
開発環境、テスト環境、本番環境でスキーマを分ける方法もあります。
- dev:開発用スキーマ(自由に実験できる)
- test:テスト用スキーマ(品質確認用)
- prod:本番用スキーマ(実際の運用データ)
この構成では、同じデータベース内で異なる環境を管理できるため、データベースサーバーの数を減らせます。ただし、本番データと開発データが混在するリスクもあるため、権限管理は厳重に行う必要があります。
よくあるトラブルと解決方法
スキーマは作成できても、その中にテーブルを作る権限がない場合があります。CREATE権限が必要です。スキーマの所有者であれば自動的に権限がありますが、他のユーザーの場合はGRANT CREATE ON SCHEMAで権限を付与してもらう必要があります。
スキーマ内にテーブルなどのオブジェクトが残っている場合、通常のDROP SCHEMAでは削除できません。すべて削除したい場合はCASCADEオプションを付けてください。ただし、データも完全に消えるので注意が必要です。
スキーマへのUSAGE権限とテーブルへのSELECT権限の両方が必要です。どちらか一方だけではアクセスできません。また、検索パスにそのスキーマが含まれていない場合は、完全修飾名(スキーマ名.テーブル名)で指定する必要があります。
PostgreSQLのスキーマとは何か?" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
スキーマを使うメリットと活用場面" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
基本的なスキーマ作成方法" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
スキーマ内にテーブルを作成する方法" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
検索パスの設定と活用" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
スキーマの削除方法" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
スキーマの名前変更とその他の操作" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
スキーマとアクセス権限の管理" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
実践的なスキーマ設計例" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">
よくあるトラブルと解決方法" onerror="this.onerror=null; this.src='/img/view/java-exception-introduce.jpg';">