共有する

はじめに

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という名前のデータベースが、デフォルトのデータベース設定を使用して現在のユーザーが新しいデータベースの所有者として設定されて作成されます。デフォルトのtemplate1テンプレートのプロパティは、次のpsqlメタコマンドを使用して表示できます。

\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: 新しいデータベースの文字分類を設定します。これは、どの文字が大文字、小文字、数字と見なされるかに影響するローカライゼーションオプションです。

これらは、データベースがサポートする予定の形式でデータを格納し、プロジェクトのローカライゼーション設定に合わせるのに役立ちます。

たとえば、データベースが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_BIRTHDATE_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。
  • Name: 特定の学校用品の名前。
  • Description: アイテムの簡単な説明。
  • Manufacturer: アイテム製造元の名前。
  • Color: アイテムの色。
  • Inventory: 特定の学校用品の在庫数。これは0未満であってはなりません。

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

まず、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テーブルを作成します。このテーブルには、次の列が存在する必要があります。

  • Employee ID: 一意の従業員識別番号。
  • First name: 教師のファーストネーム。
  • Last name: 教師のラストネーム。
  • Subject: 教師が教えるために雇われた科目。
  • Grade level: 教師が教えるために雇われた生徒の学年。

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

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コマンドを使用すると、他にも多くの種類の変更を行うことができます。利用可能なオプションの詳細については、PostgreSQLの公式ALTER TABLEドキュメントを確認してください。

テーブルを削除する

テーブルを削除したい場合は、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ドキュメントを確認してください。

よくある質問

はい、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

ジャスティン・エリングウッド

ジャスティンは2013年からデータベース、Linux、インフラストラクチャ、開発者ツールについて執筆しています。現在は妻と2匹のウサギと共にベルリンに住んでいます。通常、三人称で書く必要がないのは、関係者全員にとって安心です。
© . All rights reserved.