**制約(constraints)**は、列またはテーブルに対して適用される整合性制約であり、値の妥当性を自動的に制御します。これにより、以下が可能になります:
主要な制約の種類:
PRIMARY KEY — ユニークな識別子で、重複とNULLを禁止します。UNIQUE — 同じ列での値の重複を禁止します。FOREIGN KEY — リファレンシャル整合性、他のテーブルとの関連。CHECK — 任意の式の検証。NOT NULL — 列でのNULL値を禁止します。CREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id), -- foreign key price DECIMAL(10,2) CHECK (price > 0), created_at TIMESTAMP NOT NULL );
「一意のキー(UNIQUE)は自動的にNULL-SAFEであり、列における任意の数のNULL値を除外するのですか?」
実際には、ほとんどのDBMS(例:PostgreSQL、MySQL)では、UNIQUE制約はNULLの値を持つ複数の行を許可します。なぜなら、NULLは「不明」と見なされるからです。これにより、空の値の見えない重複が発生することがあります。
CREATE TABLE test ( id INT PRIMARY KEY, code VARCHAR(10) UNIQUE ); INSERT INTO test (id, code) VALUES (1, NULL), (2, NULL); -- 成功します
事例
アプリケーションではメールでの登録が許可されており、列はUNIQUEだったがNOT NULLではなかったため、テーブルにはNULL-emailのユーザーが10人ほど存在し、外部サービスとの統合に問題を引き起こしました。
事例
チケット注文システムでは、paymentsテーブルへのFOREIGN KEYを追加するのを忘れたため、注文に関連付けられていない支払いが発生し、ユーザーへの返金が困難になりました。
事例
割引に対するCHECK制約: discount > 0。境界ケース0を忘れていました。結果:システムは0より大きい割引しか受け付けず、割引がない(0)がビジネスロジックを壊しました。