PostgreSQL テーブルを変更し、列をユニークにする方法
PostgreSQL では、ALTER TABLE
コマンドを使用して既存のテーブルを変更できます。このコマンドには、列をユニークにするオプションが含まれています。ユニーク制約を設定すると、その列の値がテーブル内で重複することを防ぐことができます。
手順
- 以下のコマンドを使用して、変更するテーブルの名前を指定します。
ALTER TABLE table_name;
ADD UNIQUE
オプションを使用して、ユニークにする列の名前を指定します。
ADD UNIQUE (column_name);
例
以下の例では、users
テーブルのemail
列をユニークにします。
ALTER TABLE users
ADD UNIQUE (email);
- 既存の値がユニーク制約に違反している場合は、エラーが発生します。この問題を解決するには、重複している値を修正するか、制約を削除する必要があります。
- ユニーク制約は、インデックスを使用して実装されます。インデックスが存在しない場合は、
CREATE INDEX
コマンドを使用して作成する必要があります。 - 複数の列をユニークにするには、カンマ区切りで列名を指定します。
-- usersテーブルを作成する
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL
);
-- usersテーブルにデータを挿入する
INSERT INTO users (name, email) VALUES
('John Doe', '[email protected]'),
('Jane Doe', '[email protected]'),
('Peter Jones', '[email protected]'),
('Mary Smith', '[email protected]');
-- email列をユニークにする
ALTER TABLE users
ADD UNIQUE (email);
-- 重複したemailアドレスを持つレコードを挿入しようとするとエラーが発生する
INSERT INTO users (name, email) VALUES
('Bob Smith', '[email protected]');
-- 重複したemailアドレスを持つ既存のレコードを更新しようとするとエラーが発生する
UPDATE users
SET email = '[email protected]'
WHERE id = 3;
説明
このコード例では、以下の操作を行います。
users
テーブルを作成します。このテーブルには、id
、name
、email
という3つの列があります。users
テーブルにデータを挿入します。email
列をユニークにします。これにより、email
列の値がテーブル内で重複することを防ぎます。- 重複したemailアドレスを持つレコードを挿入しようとすると、エラーが発生します。
- この例では、
SERIAL
データ型を使用してid
列を作成しています。SERIAL
データ型は、自動的にシーケンス番号を生成します。 NOT NULL
制約を使用して、name
とemail
列がNULL値にならないようにしています。UNIQUE
制約は、email
列の値がテーブル内で重複することを防ぎます。
新しいテーブルを作成する際に、UNIQUE
制約をCREATE TABLE
ステートメント内に直接定義することができます。
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE
);
この方法では、ALTER TABLE
コマンドを使用する必要がなく、テーブル定義をより簡潔に記述できます。
CHECK制約を使用する
CHECK
制約を使用して、列の値がユニークであることを確認することもできます。ただし、CHECK
制約はUNIQUE
制約よりも非効率的な場合があります。
ALTER TABLE users
ADD CONSTRAINT unique_email CHECK (email IS UNIQUE);
トリガーを使用する
トリガーを使用して、列の値が変更されるたびに、その値がユニークであることを確認することもできます。ただし、トリガーは複雑になりやすく、デバッグも困難になる可能性があります。
CREATE OR REPLACE FUNCTION trigger_unique_email()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.email IN (
SELECT email FROM users
WHERE id != NEW.id
) THEN
RAISE EXCEPTION '重複したEmailアドレス: ' || NEW.email;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER unique_email
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW
EXECUTE PROCEDURE trigger_unique_email();
どの方法を選択するべきか
どの方法を選択するかは、状況によって異なります。
- 新しいテーブルを作成する場合は、
CREATE TABLE
ステートメント内にUNIQUE
制約を定義するのが最も簡単です。 - 既存のテーブルに列を追加する場合は、
ALTER TABLE
コマンドを使用する必要があります。 CHECK
制約やトリガーは、より複雑な要件を満たすために使用できますが、一般的には推奨されていません。
sql postgresql unique-constraint