PostgreSQLのデータ制約を極める:ENUM型、CHECK制約、DEFAULT制約、UNIQUE制約、PRIMARY KEY制約、FOREIGN KEY制約
PostgreSQL における ENUM データ型と CHECK 制約
一方、CHECK 制約 は、列の値が特定の条件を満たすように制約するものです。これは、データの整合性を保ち、誤った値がデータベースに挿入されるのを防ぐために使用されます。
ENUM データ型と CHECK 制約 を組み合わせることで、より強力なデータ検証と制約を実現できます。
具体的な例
性別 をモデル化する場合、次のように ENUM データ型と CHECK 制約を使用できます。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
この場合、gender
列には male
、female
、または other
のいずれかの値のみを格納できます。他の値を挿入しようとすると、エラーが発生します。
CREATE TABLE appointments (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
weekday ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday') NOT NULL,
CHECK (weekday IN ('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'))
);
メリット
ENUM データ型と CHECK 制約を組み合わせるメリットは次のとおりです。
- データの整合性を保つことができます。
- コードの可読性を向上させることができます。
デメリット
- 定義する値の数を増やす必要がある場合があります。
- 制約を追加することで、クエリのパフォーマンスが低下する可能性があります。
ENUM データ型と CHECK 制約は、PostgreSQL でデータの整合性を保ち、誤った値がデータベースに挿入されるのを防ぐのに役立つ強力なツールです。
補足
- PostgreSQL には、ENUM データ型以外にも、有限個の定数値を格納できるデータ型として
integer
、varchar
などがあります。 - CHECK 制約は、列だけでなく、テーブル全体にも適用できます。
PostgreSQL における ENUM データ型と CHECK 制約:サンプルコード
-- users テーブルの作成
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
-- データの挿入
INSERT INTO users (name, gender) VALUES ('John Doe', 'male');
INSERT INTO users (name, gender) VALUES ('Jane Doe', 'female');
INSERT INTO users (name, gender) VALUES ('Peter Jones', 'other');
-- データの選択
SELECT * FROM users;
-- エラーが発生する例
INSERT INTO users (name, gender) VALUES ('Mary Smith', 'invalid');
曜日 をモデル化する場合のサンプルコード:
-- appointments テーブルの作成
CREATE TABLE appointments (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
weekday ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday') NOT NULL,
CHECK (weekday IN ('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'))
);
-- データの挿入
INSERT INTO appointments (date, weekday) VALUES ('2024-04-12', 'friday');
INSERT INTO appointments (date, weekday) VALUES ('2024-04-13', 'saturday');
INSERT INTO appointments (date, weekday) VALUES ('2024-04-14', 'sunday');
-- データの選択
SELECT * FROM appointments;
-- エラーが発生する例
INSERT INTO appointments (date, weekday) VALUES ('2024-04-15', 'invalid');
説明
- 上記のコードは、PostgreSQL における ENUM データ型と CHECK 制約の使用方法を示しています。
users
テーブルには、id
、name
、gender
の 3 つの列があります。gender
列には、male
、female
、またはother
のいずれかの値のみを格納できます。appointments
テーブルには、id
、date
、weekday
の 3 つの列があります。weekday
列には、monday
、tuesday
、wednesday
... などのいずれかの値のみを格納できます。- コードには、データの挿入と選択の例も示されています。
- エラーが発生する例も示されています。
- 上記のコードはあくまで例であり、実際の用途に合わせて変更する必要があります。
- PostgreSQL には、さまざまなデータ型と制約が用意されています。詳細については、PostgreSQL のドキュメントを参照してください。
- 日本語で PostgreSQL に関する情報を提供している Web サイトもあります。
PostgreSQL におけるデータ制約の他の方法
DEFAULT 制約は、列にデフォルト値を設定するものです。これは、列に値が明示的に指定されない場合に、その値が自動的に挿入されるようにします。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL DEFAULT 'other',
CHECK (gender IN ('male', 'female', 'other'))
);
この場合、gender
列に値が明示的に指定されない場合は、デフォルト値として other
が設定されます。
NOT NULL 制約は、列が NULL 値にならないようにします。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
この場合、name
列と gender
列は NULL 値になりません。
UNIQUE 制約は、テーブル内のすべての行で列の値が重複しないようにします。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
この場合、name
列の値はすべての行で重複しません。
PRIMARY KEY 制約は、テーブル内の各行を一意に識別する列を定義します。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
この場合、id
列は PRIMARY KEY として定義されます。
FOREIGN KEY 制約は、あるテーブルの列を別のテーブルの列に参照できるようにします。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
gender ENUM('male', 'female', 'other') NOT NULL,
CHECK (gender IN ('male', 'female', 'other'))
);
CREATE TABLE addresses (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
street VARCHAR(255) NOT NULL,
city VARCHAR(255) NOT NULL,
state VARCHAR(255) NOT NULL,
zip_code VARCHAR(5) NOT NULL
);
この場合、addresses
テーブルの user_id
列は users
テーブルの id
列を参照します。
- 上記の制約は、すべて組み合わせて使用できます。
ENUM データ型と CHECK 制約以外にも、PostgreSQL にはデータ制約を定義する方法はいくつかあります。それぞれの方法には長所と短所があるので、状況に合わせて適切な方法を選択する必要があります。
postgresql postgresql-9.1