DBAtlas · データベース運用アトラス

制約(FK/CHECK/UNIQUE)の追加/無効化

Oracle

-- Add a foreign key
ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customer(id);
-- CHECK
ALTER TABLE product ADD CONSTRAINT chk_price CHECK (price >= 0);
-- Disable / enable
ALTER TABLE orders DISABLE CONSTRAINT fk_customer;
ALTER TABLE orders ENABLE CONSTRAINT fk_customer;

Oracle の制約は DISABLE/ENABLE で一時的に無効化できる(一括ロードに有用)。ENABLE VALIDATE は既存の行を検査し、NOVALIDATE は検査しない。

PostgreSQL

-- Foreign key and CHECK
ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customer(id);
ALTER TABLE product ADD CONSTRAINT chk_price CHECK (price >= 0);

-- Instead of disabling the FK: NOT VALID + validate later
ALTER TABLE orders ADD CONSTRAINT fk2 FOREIGN KEY (c_id) REFERENCES customer(id) NOT VALID;
ALTER TABLE orders VALIDATE CONSTRAINT fk2;
ALTER TABLE orders DROP CONSTRAINT fk2;

PostgreSQL には制約の DISABLE がない。大きなテーブルでロックを減らすには、NOT VALID で制約を追加し、後で VALIDATE する。ALTER TABLE ... DISABLE TRIGGER ALL は FK の内部トリガーも無効にし、superuser が必要。無効中に挿入されたデータは検証されず、再有効化しても遡って検査されない(気付かないうちに整合性が失われるリスク)。代わりに、制約を DROP して NOT VALID で再追加し、VALIDATE CONSTRAINT を実行する。

MySQL

-- Foreign key and CHECK
ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customer(id);
ALTER TABLE product ADD CONSTRAINT chk_price CHECK (price >= 0);

-- Temporarily disable FK checks for the session
SET FOREIGN_KEY_CHECKS = 0;
-- ... bulk operation ...
SET FOREIGN_KEY_CHECKS = 1;

InnoDB が必要。個別の制約を無効化する代わりに、セッションレベルの SET FOREIGN_KEY_CHECKS=0 を使用する。CHECK 制約が実際に適用されるのは MySQL 8.0.16 以降(それ以前は無視されていた)。

SQL Server

-- Foreign key and CHECK
ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customer(id);
ALTER TABLE product ADD CONSTRAINT chk_price CHECK (price >= 0);

-- Disable / re-enable (validate with WITH CHECK)
ALTER TABLE orders NOCHECK CONSTRAINT fk_customer;
ALTER TABLE orders WITH CHECK CHECK CONSTRAINT fk_customer;

SQL Server では FK/CHECK 制約を NOCHECK CONSTRAINT で無効化する。再有効化時に WITH CHECK CHECK CONSTRAINT を使用しないと、制約は「not trusted」のままとなり、クエリオプティマイザが利用できない。

MongoDB

// Constraint-like checks with schema validation rules
db.runCommand({ collMod: "product",
  validator: { $jsonSchema: { required: ["price"], properties: { price: { bsonType: "number", minimum: 0 } } } },
  validationLevel: "strict"
});
// Unique index for uniqueness
db.customer.createIndex({ email: 1 }, { unique: true });

外部キーはない(アプリケーション層で担保する)。UNIQUE に相当するのは一意インデックス。CHECK の代わりに $jsonSchema 検証を使用し、validationAction: 'warn' で無効化と同じ効果が得られる。

Redis

# Not applicable: Redis has no FK/CHECK/UNIQUE constraints. Uniqueness is enforced at the application level with SET or
# SETNX/conditional writes.
SET customer:email:sample@x.com 1 NX

リレーショナルな整合性や制約の概念はない。一意性はアプリケーション側で SET ... NX(存在しない場合のみ書き込み)や別の SET/HASH の確認で管理する。

Elasticsearch

# Not applicable: Elasticsearch has no FK/CHECK. Field types are enforced with the mapping,
# and uniqueness with a fixed _id.
PUT product/_doc/ABC-123
{ "price": 100 }

リレーションと制約はエンジンに存在しない。型チェックはマッピングで行う。UNIQUE 相当の効果には、自然キーを _id として使用する(同じ _id への書き込みは上書きされる)か、op_type=create で競合を拒否する。

DBAtlas で開く →