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


11

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

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)
)

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

回答:


3

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

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


8

いいえ、できません。ほとんどの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 ;

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



-1

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


1
次に、Fooテーブルに3つのカップルがあるとします(1,2) (2,3) (3,1)。3つの値をどのように分割すればよいですか?
ypercubeᵀᴹ

1
同意しますが、間違った提案です。
msi77 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.