シェア

はじめに

PostgreSQL およびその他のリレーショナルデータベース管理システムは、データを構造化して整理するためにデータベーステーブルを使用します。これらの 2 つの用語の定義を簡単に確認できます。

  • データベース: 異なる構造とデータのセットを互いに分離します。
  • テーブル: データ構造を定義し、データベース内の実際のデータ値を格納します。

PostgreSQL には、データベースとテーブルの中間オブジェクトとしてスキーマもあります。

Relationship between PostgreSQL databases, schemas, and tables

このガイドでは、PostgreSQL のスキーマの概念を直接扱うことはありませんが、それが存在することを知っておくことは良いことです。

代わりに、PostgreSQL データベースとテーブルを作成および破棄する方法に焦点を当てます。例では主に SQL を使用しますが、最後の方でコマンドラインを使用してこれらのタスクのいくつかを行う方法を示します。これらの代替手段は、PostgreSQL ホストへの管理者アクセス権を持っている場合に利用できる、標準の PostgreSQL インストールに含まれているツールを使用します。

このガイドで説明されているステートメントの一部、特に PostgreSQL の CREATE TABLE ステートメントには、この記事の範囲外の多くの追加オプションがあります。詳細については、PostgreSQL の公式ドキュメントをご覧ください。

前提条件

このガイドに従うには、psql コマンドラインクライアントを使用して、管理者権限を持つユーザーで PostgreSQL インスタンスにログインする必要があります。PostgreSQL インスタンスは、ローカル、リモート、またはプロバイダーによってプロビジョニングされたものにインストールできます。

具体的には、PostgreSQL ユーザーには CREATE DB 権限または Superuser である必要があります。これは、psql\du メタコマンドで確認できます。

\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

インストール時に自動的に作成される postgres スーパーユーザーには必要な権限がありますが、Create DB 権限を持つ任意のユーザーを使用できます。

新しいデータベースを作成する

psql またはその他の SQL クライアントを使用して PostgreSQL インスタンスに接続したら、SQL を使用してデータベースを作成できます。

データベースを作成するための基本的な構文は次のとおりです。

CREATE DATABASE db_name;

これにより、db_name という名前のデータベースが現在のサーバーに作成され、現在のユーザーが新しいデータベースの所有者として設定され、デフォルトのデータベース設定が使用されます。次の psql メタコマンドを使用して、デフォルトの template1 テンプレートのプロパティを表示できます。

\l template1
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(1 row)

追加のパラメータを追加して、データベースの作成方法を変更できます。一般的なオプションを以下に示します。

  • ENCODING: データベースの文字エンコーディングを設定します。
  • LC_COLLATE: データベースの照合順序、つまりソート順序を設定します。これは、項目が順序付けられるときにどのように整理されるかを決定するローカライズオプションです。
  • LC_CTYPE: 新しいデータベースの文字分類を設定します。これは、どの文字がUpperCase、LowerCase、および数字と見なされるかに影響を与えるローカライズオプションです。

これらは、データベースがサポートする予定の形式で、プロジェクトのローカライズ設定でデータを確実に保存できるようにするのに役立ちます。

たとえば、データベースが Unicode サポートで作成され、サーバー独自のロケールをオーバーライドしてアメリカ英語のローカライズを使用するようにするには(これらはすべて、上記の template1 の値と一致するため、実際には変更は発生しません)、次のように入力できます。

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

このガイドの例に従うには、インスタンスのデフォルトのロケール設定と UTF8 文字エンコーディングを使用して、school という名前のデータベースを作成します。

CREATE DATABASE school ENCODING 'UTF8';

これにより、指定した仕様を使用して新しいデータベースが作成されます。

既存のデータベースを一覧表示する

サーバーまたはクラスターで現在利用可能なデータベースを確認するには、次の SQL ステートメントを使用できます。

SELECT datname FROM pg_database;

これにより、環境内で現在定義されている各データベースが一覧表示されます。

datname
-----------
_dodb
template1
template0
defaultdb
school
(5 rows)

前述のように、psql クライアントを使用して接続している場合は、\l メタコマンドを使用してこの情報を取得することもできます。

\l

これにより、利用可能なデータベース名が、所有者、エンコーディング、ロケール設定、および権限とともに表示されます。

List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
_dodb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
defaultdb | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
school | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)

作成した school データベースが、システム上の他のデータベースの中に表示されます。これは、サーバーまたはクラスター内のデータベースの概要を把握するのに適した方法です。

データベース内にテーブルを作成する

1 つ以上のデータベースを作成したら、データを格納するためのテーブルの定義を開始できます。テーブルは、名前と定義されたスキーマで構成されており、各レコードに含める必要のあるフィールドとデータ型を決定します。

PostgreSQL CREATE TABLE 構文

CREATE TABLE ステートメントを使用してテーブルを作成できます。コマンドの簡略化された基本的な構文は、次のようになります。

CREATE TABLE table_name (
column_name TYPE [column_constraint],
[table_constraint,]
);

上記の構文のコンポーネントには、次のものが含まれます。

  • CREATE TABLE table_name: テーブルを定義する基本作成ステートメント。table_name プレースホルダーは、使用するテーブルの名前に置き換える必要があります。
  • column_name TYPE: テーブル内の基本的な列を定義します。column_name プレースホルダーは、列に使用する名前に置き換える必要があります。TYPE は、列のPostgreSQL データ型を指定します。テーブル内に格納されたデータは、受け入れられるために列構造と列データ型に準拠する必要があります。
  • column_constraint: 列制約は、列に格納できるデータにさらに制限を追加するためのオプションの制約です。たとえば、エントリが null でない、一意である、または正の整数であることを要求できます。
  • table_constraints: テーブル制約は列制約に似ていますが、複数の列の相互作用を含みます。たとえば、テーブルに DATE_OF_BIRTH がテーブルの DATE_OF_DEATH より前であることを確認するテーブル制約を持たせることができます。

IF NOT EXISTS 句を使用して条件付きでテーブルを作成する

デフォルトでは、データベース内に既に存在する PostgreSQL でテーブルを作成しようとすると、エラーが発生します。テーブルが存在しない場合にテーブルを作成したいが、既に存在する場合は続行したい場合にこの問題を回避するには、IF NOT EXISTS 句を使用できます。IF NOT EXISTS オプションの修飾子は、データベースが既に存在する場合にステートメントを無視するように PostgreSQL に指示します。

IF NOT EXISTS 句を使用するには、CREATE TABLE 構文の後、テーブル名の前にあるコマンドに挿入します。

CREATE TABLE IF NOT EXISTS table_name (
column_name TYPE [column_constraint],
[table_constraint,]
);

このバリアントは、テーブルの作成を試みます。指定されたデータベース内にその名前のテーブルが既に存在する場合、PostgreSQL はエラーで失敗する代わりに、テーブル名が既に取得されていることを示す警告をスローします。

PostgreSQL でテーブルを作成する方法

上記の構文は、基本的なテーブルを作成するのに十分です。例として、school データベース内に 2 つのテーブルを作成します。1 つのテーブルは supplies と呼ばれ、もう 1 つは teachers と呼ばれます。

Entity relationship diagrams for supplies and teachers tables

supplies テーブルには、次のフィールドが必要です。

  • ID: 各タイプの学用品の一意の ID。
  • 名前: 特定の学用品の名前。
  • 説明: 品目の簡単な説明。
  • 製造元: 品目の製造元の名前。
  • 色: 品目の色。
  • 在庫: 特定のタイプの学用品の在庫数。これは 0 未満であってはなりません。

次の SQL を使用して、上記の品質を持つ supplies テーブルを作成できます。

まず、psql で作成した school データベースに切り替えるには、次のように入力します。

\c school

これにより、今後のコマンドのターゲットとなるデータベースが変更されます。プロンプトはデータベースを反映するように変更されます。

次に、次のステートメントで supplies テーブルを作成します。

CREATE TABLE supplies (
id INT PRIMARY KEY,
name VARCHAR,
description VARCHAR,
manufacturer VARCHAR,
color VARCHAR,
inventory int CHECK (inventory > 0)
);

これにより、school データベース内に supplies テーブルが作成されます。PRIMARY KEY 列制約は、テーブル内のレコードを一意に識別できる列を示すために使用される特別な制約です。そのため、制約は、列が null にできず、一意である必要があることを指定します。PostgreSQL は、クエリ速度を向上させるために主キー列のインデックスを作成します。

新しいテーブルが存在することを確認するには、次のように入力します。

\dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+---------
public | supplies | table | doadmin
(1 row)

スキーマが意図した設計を反映していることを確認するには、次のように入力します。

\d supplies
Table "public.supplies"
Column | Type | Collation | Nullable | Default
--------------+-------------------+-----------+----------+---------
id | integer | | not null |
name | character varying | | |
description | character varying | | |
manufacturer | character varying | | |
color | character varying | | |
inventory | integer | | |
Indexes:
"supplies_pkey" PRIMARY KEY, btree (id)
Check constraints:
"supplies_inventory_check" CHECK (inventory > 0)

指定した各列とデータ型を確認できます。inventory 列に定義した列制約は、最後にリストされています。

次に、teachers テーブルを作成します。このテーブルには、次の列が必要です。

  • 従業員 ID: 一意の従業員識別番号。
  • : 教師の名前。
  • : 教師の姓。
  • 科目: 教師が教えるために雇用されている科目。
  • 学年: 教師が教えるために雇用されている生徒の学年。

次の SQL を使用して、上記のスキーマを持つ teachers テーブルを作成します。

CREATE TABLE teachers (
id INT PRIMARY KEY,
first_name VARCHAR,
last_name VARCHAR,
subject VARCHAR,
grade_level int
);

主キーと外部キーを使用してテーブルを作成する方法

主キーと外部キーを使用してテーブルを作成する方法については、他の PostgreSQL ガイドをご覧ください。主キーと外部キーは、PostgreSQL 内のデータベース制約のタイプです。

主キーは、同じテーブル内の行全体で一意であることが保証されている特別な列または列です。すべての主キーは、特定の行を一意に識別するために使用できます。主キーは、各行に主キー列の一意の値があることを保証するだけでなく、その列に NULL 値を含む行がないことも保証します。多くの場合、PostgreSQL の主キーは、自動的に割り当てられるインクリメント主キーを指定するために、次の形式を使用します:id SERIAL PRIMARY KEY

外部キーは、あるテーブルの列または列が別のテーブルに含まれる値と一致することを保証する方法です。これは、テーブル間の参照整合性を保証するのに役立ちます。

PostgreSQL でテーブルを表示する方法

PostgreSQL では、探している情報に応じて、いくつかの異なる方法でテーブルを一覧表示できます。

データベース内で利用可能なテーブルを確認する場合は、psql クライアントに含まれている \dt メタコマンドを使用して、上記で説明したようにすべてのテーブルを一覧表示できます。

\dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+---------
public | supplies | table | doadmin
public | teachers | table | doadmin
(2 rows)

テーブルのスキーマが仕様と一致していることを確認することもできます。

\d teachers
Table "public.teachers"
Column | Type | Collation | Nullable | Default
-------------+-------------------+-----------+----------+---------
id | integer | | not null |
first_name | character varying | | |
last_name | character varying | | |
subject | character varying | | |
grade_level | integer | | |
Indexes:
"teachers_pkey" PRIMARY KEY, btree (id)

teachers テーブルは、定義と一致しているようです。

テーブルを変更する

PostgreSQL で既存のテーブルのスキーマを変更する必要がある場合は、ALTER TABLE コマンドを使用できます。ALTER TABLE コマンドは CREATE TABLE コマンドと非常によく似ていますが、既存のテーブルで動作します。

テーブル変更構文

PostgreSQL でテーブルを変更するための基本的な構文は次のようになります。

ALTER TABLE <table_name> <change_command> <change_parameters>

<change_command> は、テーブルに異なるオプションを設定したり、列を追加または削除したり、型または制約を変更したりするなど、実行する変更の正確なタイプを示します。コマンドの <change_parameters> 部分には、PostgreSQL が変更を完了するために必要な追加情報が含まれています。

テーブルに列を追加する

ADD COLUMN 変更コマンドを使用して、PostgreSQL テーブルに列を追加できます。変更パラメータには、CREATE TABLE コマンドで指定する場合と同じように、列名、型、およびオプションが含まれます。

たとえば、some_table という名前のテーブルに text 型の missing_column という名前の列を追加するには、次のように入力します。

ALTER TABLE some_table ADD COLUMN missing_column text;

テーブルから列を削除する

代わりに、既存の列を削除する場合は、代わりに DROP COLUMN コマンドを使用できます。変更パラメータとして削除する列の名前を指定する必要があります。

ALTER TABLE some_table DROP COLUMN useless_column;

列のデータ型を変更する

PostgreSQL が特定の列に使用するデータ型を変更するには、ALTER COLUMN 変更コマンドを SET DATA TYPE 列コマンドで使用できます。パラメータには、列名、その新しい型、および古い型を新しい型に変換する方法を指定するためのオプションの USING 句が含まれます。

たとえば、resident テーブルの id 列の値を明示的なキャストを使用して int に設定するには、次のように入力できます。

ALTER TABLE resident ALTER COLUMN id SET DATA TYPE int USING id::int;

その他のテーブル変更

他の多くの種類の変更は、ALTER TABLE コマンドで実現できます。利用可能なオプションの詳細については、ALTER TABLE の PostgreSQL 公式ドキュメントをご覧ください。

テーブルを削除する

テーブルを削除する場合は、DROP TABLE SQL ステートメントを使用できます。これにより、テーブルとテーブル内に格納されているすべてのデータが削除されます。

基本的な構文は次のようになります。

DROP TABLE table_name;

これにより、テーブルが存在する場合は削除され、テーブル名が存在しない場合はエラーがスローされます。

テーブルが存在する場合は削除し、存在しない場合は何も実行しない場合は、ステートメント内に IF EXISTS 修飾子を含めることができます。

DROP TABLE IF EXISTS table_name;

他のテーブルまたはオブジェクトに依存関係があるテーブルは、それらの依存関係が存在する間はデフォルトで削除できません。エラーを回避するには、オプションで CASCADE パラメータを含めることができます。これにより、テーブルとともにすべての依存関係が自動的に削除されます。

DROP TABLE table_name CASCADE;

削除するテーブルを参照する外部キー制約を持つテーブルがある場合、その制約は自動的に削除されます。

先ほど作成した supplies テーブルを削除するには、次のように入力します。

DROP TABLE supplies;

teachers データベースは、データベースを削除するステートメントがテーブルのようなすべての子オブジェクトも削除することを実証するために保持します。

データベースを削除する

DROP DATABASE ステートメントは、指定されたデータベースを削除するように PostgreSQL に指示します。基本的な構文は次のようになります。

DROP DATABASE database_name;

database_name プレースホルダーを、削除するデータベースの名前に置き換えます。これにより、データベースが見つかった場合は削除されます。データベースが見つからない場合は、エラーが発生します。

DROP DATABASE some_database;
ERROR: database "some_database" does not exist

データベースが存在する場合に削除し、存在しない場合は何もしないようにするには、オプションの IF EXISTS オプションを含めてください。

DROP DATABASE IF EXISTS some_database;
NOTICE: database "some_database" does not exist, skipping
DROP DATABASE

これはデータベースを削除するか、見つからない場合は何もしません。

このガイドで使用した school データベースを削除するには、システム上の既存のデータベースを一覧表示します。

\l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
_dodb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
defaultdb | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
school | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)

削除したくないデータベースのいずれかに新しい接続を開きます。

\c defaultdb

新しい接続が開いたら、次のコマンドで school データベースを削除します。

DROP DATABASE school;

これにより、school データベースが、その中に定義されている teachers テーブルとともに削除されます。

SQL を使用してここまで進めてきた場合は、ここで終了するか、結論 にスキップできます。コマンドラインからデータベースを作成および削除する方法について学習したい場合は、次のセクションに進んでください。

管理コマンドラインツールを使用してデータベースを作成および削除する

PostgreSQL がインストールされているサーバーまたはクラスターへのシェルアクセスがある場合、データベースの作成と削除に役立つ追加のコマンドラインツールにアクセスできる場合があります。createdb および dropdb コマンドは、PostgreSQL のインストール時にバンドルされています。

コマンドラインから新しいデータベースを作成する

createdb コマンド(PostgreSQL への管理者アクセス権を持つシステムユーザーが実行する必要があります)の基本的な構文は次のとおりです。

createdb db_name

これにより、デフォルト設定 を使用して、PostgreSQL 内に db_name という名前のデータベースが作成されます。

このコマンドは、先ほど見た SQL のバリアントと同様に、その動作を変更するためのオプションも受け入れます。これらのオプションの詳細については、man createdb で確認できます。最も重要なオプションのいくつかを以下に示します。

これらは、データベースがサポートする予定の形式で、プロジェクトのローカライズ設定でデータを確実に保存できるようにするのに役立ちます。

たとえば、データベースが Unicode サポートで作成され、サーバー自身のロケールをオーバーライドしてアメリカ英語のローカライズを使用するようにするには、次のように入力できます。

createdb --encoding=UTF8 --locale=en_US db_name

正しい権限を持っていると仮定すると、データベースは指定に従って作成されます。

このガイドの例に従うには、デフォルトのロケールと UTF8 文字エンコーディングを使用して school という名前のデータベースを作成できます。次のように入力します。

createdb --encoding=UTF8 school

その後、psql を使用してデータベースに接続し、通常どおりにテーブルを設定できます。

コマンドラインからデータベースを削除する

dropdb コマンドは、DROP DATABASE SQL ステートメントを反映しています。基本的な構文は次のとおりです。

dropdb database_name

削除したいデータベースを参照するように、database_name プレースホルダーを変更します。

デフォルトでは、このコマンドは、指定されたデータベースが見つからない場合にエラーになります。これを避けるには、オプションの --if-exists フラグを含めることができます。

dropdb --if-exists database_name

これにより、指定されたデータベースが存在する場合は削除されます。存在しない場合は、何も行いません。

先ほど作成した school データベースを削除するには、次のように入力します。

dropdb school

これにより、データベースと、その中のテーブルなどのすべての子要素が削除されます。

結論

この記事では、PostgreSQL 内でデータベースとテーブルを作成および削除する方法の基本について説明しました。これらは、データベースシステムをセットアップし、データの構造を定義するために必要な最も基本的なコマンドの一部です。

前述のように、この PostgreSQL チュートリアルで説明した SQL ステートメント、特に CREATE TABLE ステートメントには、PostgreSQL の動作を変更するために使用できる追加のパラメーターが多数あります。これらの詳細については、PostgreSQL 公式ドキュメント を参照してください。

FAQ

はい、PostgreSQL はデータベースとテーブルの両方を作成する際に IF NOT EXISTS の使用をサポートしています。以下は、テーブル作成にこの句を使用する方法を示しています。

CREATE TABLE IF NOT EXISTS table_name (
column_name TYPE [column_constraint],
[table_constraint,]
);

ダンプ (pg_dump) からデータベースを作成するために、PostgreSQL は ユーティリティプログラム pg_restore を提供しています。

このプログラムは、ダンプ時の状態と同じ状態でデータベースを再作成します。構文例は次のようになります。

pg_restore [connection-option...][option...][filename]

PostgreSQL でデータベースを作成するには、createdb コマンド を使用します。構文は次のとおりです。

createdb db_name

DROP DATABASE ステートメントは、PostgreSQL に指定されたデータベースを削除するように指示します。基本的な構文は次のようになります。

DROP DATABASE database_name;

特定の列の データ型 を変更するには、ALTER COLUMN 変更コマンドを SET DATA TYPE 列コマンドとともに使用します。

基本的な構文には、列名、新しい型、および古い型の変換を指定するためのオプションの USING 句が含まれます。

ALTER TABLE resident ALTER COLUMN id SET DATA TYPE int USING id::int;
著者について
Justin Ellingwood

Justin Ellingwood

Justin は、2013 年からデータベース、Linux、インフラストラクチャ、および開発者ツールについて執筆しています。彼は現在、妻と 2 羽のウサギとともにベルリンに住んでいます。彼は通常、三人称で書く必要はありません。これは関係者全員にとって安心です。