PostgreSQL 入門

PostgreSQL におけるデータベースの作成

1. データベース作成の基本構文

PostgreSQLでデータベースを作成するための最も中心となるSQLコマンドは CREATE DATABASE です。このコマンドの最もシンプルな形式は以下の通りです。

CREATE DATABASE データベース名;

ここで指定する データベース名 は、作成したい新しいデータベースの名前です。この名称は、対象のPostgreSQL クラスター(Cluster) 内でユニーク(一意)である必要がある点に注意してください。

例:

CREATE DATABASE my_first_database;

このコマンドを実行すると、システムは my_first_database という名前のデータベースを作成します。この際、システムテンプレートデータベース(デフォルトでは通常 template1)のすべてのデフォルト設定が自動的に継承されます。

2. CREATE DATABASE の高度なオプションとパラメータ

基本構文は非常にシンプルですが、CREATE DATABASE コマンドには豊富なオプションが用意されており、新しいデータベースの振る舞いや特性を詳細にカスタマイズできます。これらのオプションにより、文字エンコーディング、ロケール設定、テーブルスペースなどの主要な属性を制御できます。

2.1 エンコーディング (Encoding)

ENCODING オプションは、データベース内でテキストデータを保存する際に使用する文字セットを指定します。一般的なエンコーディングには、UTF8(モダンなアプリケーションで最も推奨される設定)、LATIN1SQL_ASCII などがあります。テキストデータの文字化けを防ぐために、適切なエンコーディングを指定することは非常に重要です。

CREATE DATABASE my_database 
    ENCODING 'UTF8';

この例では、UTF-8 エンコーディングを採用したデータベースを作成しています。UTF-8 は非常に汎用的なエンコーディング方式であり、世界中のほぼすべての言語の文字を完全にサポートしています。

  • 正例: 中国語、英語、日本語、スペイン語を含むユーザー名や住所を保存するアプリケーションを開発する場合、UTF8 エンコーディングを使用することで、これらすべての文字が正しく保存され、データの破損や文字化けが発生しません。
  • 反例: もし誤って SQL_ASCII を使用した場合、データベースは基本的な英数字しか安全に保存できず、日本語や特殊記号を保存しようとするとデータが失われたり文字化けしたりします。

2.2 ロケール (Locale: LC_COLLATE と LC_CTYPE)

ロケール設定は、データベースのソート順序(LC_COLLATE)と文字分類ルール(LC_CTYPE)を決定します。これらの設定は、文字列の比較方法や、UPPER()(大文字変換)、LOWER()(小文字変換)といった関数の動作に深く影響します。

CREATE DATABASE my_database 
    ENCODING 'UTF8' 
    LC_COLLATE = 'en_US.UTF-8' 
    LC_CTYPE = 'en_US.UTF-8';

この例では、UTF-8 エンコーディングを設定するだけでなく、ロケールをアメリカ英語(U.S. English)に設定しています。

  • LC_COLLATE はソート順を定義し、ORDER BY クエリを使用する際に文字列がどのように並ぶかを決定します。
  • LC_CTYPE は文字分類に影響を与えます。例えば、システムがある文字を文字として扱うか数字として扱うか、あるいは大文字・小文字変換のルールなどを決定します。
  • 正例: ECサイトにおいて、商品名をアルファベット順や五十音順にソートしたい場合、正しい LC_COLLATE を設定することで、現地のユーザーの読解習慣に合ったソート結果を提供できます。
  • 反例: ドイツ人ユーザー向けのデータベースで、LC_COLLATE が誤って中国語や英語に設定されている場合、ドイツ語特有の文字(ä, ö, ü など)を含むテキストのソート順が著しく乱れることになります。

2.3 テーブルスペース (Tablespace)

PostgreSQLにおける テーブルスペース (Tablespace) とは、ファイルシステム上の物理的なディレクトリパスを指し、データ表やインデックスなどのデータベースオブジェクトを格納するために使用されます。デフォルトでは、すべての新しいデータベースはデフォルトのテーブルスペースに作成されますが、TABLESPACE オプションを使用してカスタムのテーブルスペースを指定することも可能です。これはパフォーマンスのチューニングや、異なるディスク間でのストレージ管理によく利用されます。

カスタムテーブルスペースを使用するには、まずテーブルスペースを作成する必要があります(通常、スーパーユーザー権限が必要です)。

CREATE TABLESPACE my_tablespace 
    LOCATION '/path/to/my/tablespace';

その後、データベース作成時にそれを指定します。

CREATE DATABASE my_database 
    TABLESPACE my_tablespace;

これにより、my_database のすべてのデータファイルは、my_tablespace が指し示すディレクトリに物理的に保存されます。

  • 正例: サーバーに高速な SSD と大容量だが低速な HDD が搭載されているとします。頻繁に読み書きが発生するホットなデータベースのテーブルスペースを SSD 上に作成し、アーカイブ用の履歴データのテーブルスペースを HDD 上に作成する戦略をとることで、システム全体のコストパフォーマンスを大幅に最適化できます。
  • 反例: すべてのデータベースをデフォルトの単一ディスクに詰め込むと、データ量が急増したり同時実行数が高まった際に、深刻なディスク I/O ボトルネックを引き起こしやすくなります。

2.4 テンプレート (Template)

新しいデータベースを作成する際、PostgreSQLは実際には既存のテンプレートデータベースを「コピー」することで作成を行っています。デフォルトのテンプレートは template1 ですが、TEMPLATE オプションを使用して別のテンプレートを指定することも可能です。これは、特定のプラグインやプリセット設定を持つデータベースを一括作成したい場合に非常に便利です。

CREATE DATABASE my_database 
    TEMPLATE template0;

上記のコマンドは template0 をテンプレートとして使用します。template0 はPostgreSQLが提供する最も原始的でクリーンなテンプレートです。これを使用することで、template1 に誰かが追加したかもしれないカスタム設定や不要なデータを継承せずにデータベースを作成できます。

  • 正例: 事前に必要な 拡張機能 (Extension) (空間データを扱う PostGIS など)をインストールし、特定のセキュリティポリシーを設定した独自のテンプレートデータベースを作成しておきます。その後、それらの機能を必要とする新しいビジネス用データベースを作成する際、そのカスタムテンプレートを指定するだけで素早く生成できます。
  • 反例: デフォルトの template1 で不用意にテーブルを作成したりグローバル設定を変更したりすると、将来作成されるすべての新しいデータベースにそれらの(不要な可能性が高い)テーブルや設定が引き継がれ、システムが極めて混乱した状態になります。

2.5 コネクション制限 (Connection Limit)

CONNECTION LIMIT オプションは、そのデータベースへの同時接続の最大数を設定するために使用されます。これはリソース管理および過負荷防止のための重要なメカニズムです。

CREATE DATABASE my_database 
    CONNECTION LIMIT 100;

これにより、my_database への最大同時接続数が 100 に制限されます。この上限に達すると、新しい接続の試みは拒否されます。

  • 正例: 低スペックなサーバーにデプロイされた小規模なアプリケーションにおいて、適切な接続制限を設定することで、突発的な大量リクエストによってデータベースがダウンするのを防ぎ、コアサービスの安定性を維持できます。
  • 反例: 接続制限を極端に低く設定しすぎると、正常なユーザーのリクエストが頻繁に拒否され、サービス中断のような状態を招きます。逆に制限を設定しない場合(デフォルト)、悪意のある攻撃やコードのバグ(コネクションプールのリークなど)によってシステムメモリが使い果たされるリスクがあります。

2.6 オーナー (Owner)

OWNER オプションは、新しいデータベースの所有者となる ロール(ユーザー) を指定します。データベースのオーナーは、データベース設定の変更や他のユーザーへの権限付与など、非常に高い特権を持ちます。

CREATE DATABASE my_database 
    OWNER my_user;

このコマンドは my_database を作成し、即座にその所有権を my_user に付与します。

  • 正例: 複数の部署で共有されているデータベースクラスターにおいて、各部署に特定のユーザーを割り当て、データベース作成時にその部署の責任者アカウントをオーナーに指定することで、権限の物理的な隔離と委譲を実現できます。
  • 反例: オーナーを明示的に指定しない場合、データベースはデフォルトで CREATE DATABASE コマンドを実行したユーザー(通常はスーパー管理者の postgres)のものになります。これは最小権限の原則に反し、セキュリティリスクを増大させます。

3. 実戦シーンでの活用例

上記のオプションを組み合わせて、実際のエンジニアリング現場でどのようにデータベースが作成されるかを見てみましょう。

シナリオ 1:Webアプリケーション用データベースの作成

CREATE DATABASE web_app 
    ENCODING 'UTF8' 
    LC_COLLATE = 'en_US.UTF-8' 
    LC_CTYPE = 'en_US.UTF-8' 
    OWNER web_user 
    CONNECTION LIMIT 50;

このコードは、Webアプリケーション用に web_app という名前のデータベースを作成します。汎用性の高い UTF-8 エンコーディングを強制し、アメリカ英語のロケール規則を設定、管理権限を web_user に付与し、リソース保護のために最大同時接続数を 50 に制限しています。

シナリオ 2:データウェアハウス (Data Warehousing) 用データベースの作成

-- まずスーパーユーザーが高速ディスクを指すテーブルスペースを作成
CREATE TABLESPACE fast_disk LOCATION '/mnt/ssd/data'; 

-- データウェアハウス用データベースを作成
CREATE DATABASE data_warehouse 
    ENCODING 'UTF8' 
    TABLESPACE fast_disk 
    OWNER data_admin;

このシナリオでは、データウェアハウスの膨大なデータスループット要件に対応するため、まず高速な SSD ディスク (/mnt/ssd/data) 上に fast_disk という名前のテーブルスペースを作成しました。その後、data_warehouse データベースをこの高速テーブルスペース上に直接構築し、専任の data_admin によって管理されるようにしています。

シナリオ 3:カスタムテンプレートを使用したデータベースの作成

-- 1. カスタムテンプレートデータベースを作成 (デフォルトの template1 をベースにする)
CREATE DATABASE my_template WITH TEMPLATE template1; 

-- 2. my_template に接続し (コマンドライン操作: \c my_template)、拡張機能をインストール
CREATE EXTENSION postgis;  

-- 3. 設定済みのテンプレートを使用して最終的な新しいデータベースを作成
CREATE DATABASE new_database WITH TEMPLATE my_template;

この方法で作成された new_database は、作成された瞬間にすでに postgis 拡張機能がインストールされており、手動での再設定は不要です。