web-dev-qa-db-ja.com

2つの列が同じ値にならないようにできますか

このようなテーブルがあれば

CREATE TABLE foo (
   id INT NOT NULL AUTO_INCREMENT,
   aa INT NOT NULL,
   bb INT NOT NULL,
   PRIMARY KEY (id),
   UNIQUE KEY (aa, bb),
   CONSTRAINT aa_ref FOREIGN KEY (aa) REFERENCES bar (id),
   CONSTRAINT bb_ref FOREIGN KEY (bb) REFERENCES bar (id)
)

アプリケーションレベルのロジックを使用するか、トリガーを強制的にBEFORE INSERTで失敗させる以外に、aa != bbを確認する方法はありますか?

11
Nifle

MySQLはCHECK contrsaintsを直接サポートしていませんが、最近の十分なバージョンがある場合、SIGNALを介したトリガーとエラー発生をサポートしているため、BEFORE INSERTBEFORE UPDATEを定義できます。データをチェックし、目的の制約が満たされない場合にエラーを発生させるトリガー。

もちろん、これはチェック制約のネイティブサポートよりも効率が悪いため、その構造に対して大量の書き込みを実行している場合は、トリガーがアプリケーションに悪影響を与えている場合に備えて、パフォーマンスの違いを分析してください。

3
David Spillett

いいえ、できません。ほとんどのDBMS(Postgres、SQL-Server、Oracle、DB2など)では、CHECK制約を追加するだけです。

ALTER TABLE foo 
  ADD CONSTRAINT aa_cannot_be_equal_to_bb_CHK
    CHECK (aa <> bb) ;

参照制約のみを使用して、これをMySQLで実現する方法はありません。トリガーの他に、2つの列に同じ値を設定し、常にビューからテーブルにアクセスすることで行を無視することができます。

CREATE VIEW foo_correct AS
SELECT id, aa, bb
FROM foo
WHERE aa <> bb ;

または、制約を処理する(ストアドプロシージャ)を使用して挿入操作と更新操作を制限し、制約を満たさないデータを挿入(または変更)できないようにすることもできます。

8
ypercubeᵀᴹ

朗報!!

Mysqlはチェック制約をサポートしています

https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

問題の両方の列が同じBarテーブルを参照しています。 Barテーブルを2つに分割して、異なる値のセットを持つIDを含めることができますか?

0
msi77