はじめに
PostgreSQLやその他のリレーショナルデータベース管理システムは、データを構造化し整理するためにデータベースとテーブルを使用します。これらの2つの用語の定義を簡単に確認しましょう。
PostgreSQLには、データベースとテーブルの間にスキーマと呼ばれる中間オブジェクトもあります。
このガイドでは、PostgreSQLのスキーマの概念を直接扱うことはありませんが、それが存在することを知っておくと良いでしょう。
代わりに、PostgreSQLデータベースとテーブルの作成と破棄に焦点を当てます。例は主にSQLを使用しますが、最後の方で、コマンドラインを使用してこれらのタスクのいくつかを行う方法を示します。これらの代替手段は、PostgreSQLホストへの管理アクセスがある場合に利用できる、標準のPostgreSQLインストールに含まれるツールを使用します。
このガイドで扱うステートメントの一部、特にPostgreSQLのCREATE TABLE
ステートメントには、この記事の範囲外の多くの追加オプションがあります。追加情報が必要な場合は、公式PostgreSQLドキュメントでさらに確認してください。
前提条件
このガイドに従うには、psql
コマンドラインクライアントを使用して、管理者権限を持つユーザーでPostgreSQLインスタンスにログインする必要があります。PostgreSQLインスタンスは、ローカル、リモート、またはプロバイダーによってプロビジョニングされている場合があります。
具体的には、PostgreSQLユーザーにはCREATE DB
権限またはSuperuser
である必要があります。psql
の\du
メタコマンドで確認できます。
\du
List of rolesRole 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 databasesName | 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_nameENCODING '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-----------_dodbtemplate1template0defaultdbschool(5 rows)
前述のとおり、psql
クライアントを使用して接続している場合は、\l
メタコマンドでもこの情報を取得できます。
\l
これにより、利用可能なデータベース名と、その所有者、エンコーディング、ロケール設定、および権限が表示されます。
List of databasesName | 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/postgrestemplate1 | 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
という名前です。
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 relationsSchema | 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 relationsSchema | Name | Type | Owner--------+----------+-------+---------public | supplies | table | doadminpublic | 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, skippingDROP DATABASE
これにより、データベースが削除されるか、見つからない場合は何もしません。
このガイドで使用したschool
データベースを削除するには、システム上の既存のデータベースを一覧表示します。
\l
List of databasesName | 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/postgrestemplate1 | 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
で確認できます。最も重要なオプションのいくつかは次のとおりです。
--encoding=
: データベースの文字エンコーディングを設定します。--locale=
: データベースのロケールを設定します。
これらは、データベースがサポートする予定の形式でデータを格納し、プロジェクトのローカライゼーション設定に合わせるのに役立ちます。
たとえば、データベースが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ドキュメントを確認してください。
Prismaを使用してPostgreSQLで開発する場合、通常、Prisma Migrateを使用してデータベースとテーブルを作成します。Prisma Migrateを使用した開発に関するガイドでその使用方法を学ぶことができます。
よくある質問
はい、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;