PostgreSQL-制約
制約は、テーブルのデータ列に適用されるルールです。これらは、無効なデータがデータベースに入力されるのを防ぐために使用されます。これにより、データベース内のデータの正確性と信頼性が保証されます。
制約は、列レベルまたはテーブルレベルにすることができます。列レベルの制約は1つの列にのみ適用されますが、テーブルレベルの制約はテーブル全体に適用されます。列のデータ型を定義すること自体が制約です。たとえば、タイプDATEの列は、列を有効な日付に制約します。
以下は、PostgreSQLで利用可能な一般的に使用される制約です。
NOT NULL Constraint −列にNULL値を含めることができないようにします。
UNIQUE Constraint −列のすべての値が異なることを確認します。
PRIMARY Key −データベーステーブルの各行/レコードを一意に識別します。
FOREIGN Key −他のテーブルの列に基づいてデータを制約します。
CHECK Constraint − CHECK制約は、列のすべての値が特定の条件を満たすことを保証します。
EXCLUSION Constraint − EXCLUDE制約は、指定された演算子を使用して指定された列または式で2つの行が比較された場合、これらの比較のすべてがTRUEを返すわけではないことを保証します。
NOTNULL制約
デフォルトでは、列はNULL値を保持できます。列にNULL値を持たせたくない場合は、この列にそのような制約を定義して、その列にNULLが許可されないように指定する必要があります。NOT NULL制約は、常に列制約として記述されます。
NULLは、データがないことと同じではありません。むしろ、それは未知のデータを表しています。
例
たとえば、次のPostgreSQLステートメントはCOMPANY1という名前の新しいテーブルを作成し、5つの列を追加します。そのうちの3つ、IDとNAMEとAGEは、NULL値を受け入れないように指定します-
CREATE TABLE COMPANY1(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
一意の制約
UNIQUE制約は、2つのレコードが特定の列で同じ値を持つことを防ぎます。たとえば、COMPANYテーブルでは、2人以上が同じ年齢にならないようにすることができます。
例
たとえば、次のPostgreSQLステートメントはCOMPANY3という新しいテーブルを作成し、5つの列を追加します。ここでは、AGE列がUNIQUEに設定されているため、同じ年齢の2つのレコードを持つことはできません。
CREATE TABLE COMPANY3(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL UNIQUE,
ADDRESS CHAR(50),
SALARY REAL DEFAULT 50000.00
);
主キーの制約
PRIMARY KEY制約は、データベーステーブル内の各レコードを一意に識別します。UNIQUE列はさらに多くすることができますが、テーブルには主キーが1つだけあります。データベーステーブルを設計するときは、主キーが重要です。主キーは一意のIDです。
これらを使用して、テーブルの行を参照します。テーブル間の関係を作成するとき、主キーは他のテーブルの外部キーになります。「長年のコーディング監視」のため、SQLiteでは主キーがNULLになる可能性があります。これは他のデータベースには当てはまりません
主キーはテーブル内のフィールドであり、データベーステーブル内の各行/レコードを一意に識別します。主キーには一意の値が含まれている必要があります。主キー列にNULL値を含めることはできません。
テーブルには、単一または複数のフィールドで構成される主キーを1つだけ含めることができます。複数のフィールドが主キーとして使用される場合、それらはcomposite key。
テーブルのいずれかのフィールドに主キーが定義されている場合、そのフィールドの値が同じである2つのレコードを持つことはできません。
例
IDを主キーとしてCOMAPNY4テーブルを作成した上記のさまざまな例をすでに見てきました。
CREATE TABLE COMPANY4(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
外部キー制約
外部キー制約は、列(または列のグループ)の値が別のテーブルのある行に表示される値と一致する必要があることを指定します。これにより、2つの関連するテーブル間の参照整合性が維持されると言えます。制約が外部であるため、これらは外部キーと呼ばれます。つまり、テーブルの外です。外部キーは、参照キーと呼ばれることもあります。
例
たとえば、次のPostgreSQLステートメントはCOMPANY5という名前の新しいテーブルを作成し、5つの列を追加します。
CREATE TABLE COMPANY6(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
たとえば、次のPostgreSQLステートメントは、3つの列を追加するDEPARTMENT1という新しいテーブルを作成します。列EMP_IDは外部キーであり、テーブルCOMPANY6のIDフィールドを参照します。
CREATE TABLE DEPARTMENT1(
ID INT PRIMARY KEY NOT NULL,
DEPT CHAR(50) NOT NULL,
EMP_ID INT references COMPANY6(ID)
);
CHECK制約
CHECK制約を使用すると、条件はレコードに入力されている値をチェックできます。条件がfalseと評価された場合、レコードは制約に違反し、テーブルに入力されません。
例
たとえば、次のPostgreSQLステートメントはCOMPANY5という名前の新しいテーブルを作成し、5つの列を追加します。ここでは、SALARY列を含むCHECKを追加して、SALARYをゼロにすることはできないようにします。
CREATE TABLE COMPANY5(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL CHECK(SALARY > 0)
);
除外制約
除外制約により、指定された演算子を使用して指定された列または式で2つの行が比較された場合、これらの演算子の比較の少なくとも1つがfalseまたはnullを返します。
例
たとえば、次のPostgreSQLステートメントはCOMPANY7という新しいテーブルを作成し、5つの列を追加します。ここでは、EXCLUDE制約を追加します-
CREATE TABLE COMPANY7(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT,
AGE INT ,
ADDRESS CHAR(50),
SALARY REAL,
EXCLUDE USING gist
(NAME WITH =,
AGE WITH <>)
);
ここで、USINGの要点は、構築して施行に使用するインデックスのタイプです。
データベースごとに1回、コマンドCREATE EXTENSIONbtree_gistを実行する必要があります。これにより、プレーンスカラーデータ型の除外制約を定義するbtree_gist拡張機能がインストールされます。
年齢は同じでなければならないことを強制したので、テーブルにレコードを挿入してこれを確認しましょう-
INSERT INTO COMPANY7 VALUES(1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY7 VALUES(2, 'Paul', 32, 'Texas', 20000.00 );
INSERT INTO COMPANY7 VALUES(3, 'Paul', 42, 'California', 20000.00 );
最初の2つのINSERTステートメントでは、レコードがCOMPANY7テーブルに追加されます。3番目のINSERTステートメントでは、次のエラーが表示されます-
ERROR: conflicting key value violates exclusion constraint "company7_name_age_excl"
DETAIL: Key (name, age)=(Paul, 42) conflicts with existing key (name, age)=(Paul, 32).
制約の削除
制約を削除するには、その名前を知っている必要があります。名前がわかっていれば、簡単に落とすことができます。それ以外の場合は、システムで生成された名前を見つける必要があります。ここでは、psqlコマンドの\ dテーブル名が役立ちます。一般的な構文は次のとおりです。
ALTER TABLE table_name DROP CONSTRAINT some_name;