books
という名前の次のテーブルを作成しました。
CREATE TABLE IF NOT EXISTS `books` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
books
テーブルの2冊の本を比較するために、compareという別のタブレットを作成しました。
CREATE TABLE IF NOT EXISTS `compare` (
`id_1` BIGINT UNSIGNED NOT NULL,
`id_2` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id_1`,`id_2`),
FOREIGN KEY (`id_1`) REFERENCES books(`id`),
FOREIGN KEY (`id_2`) REFERENCES books(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
以前は期待どおりに機能しますが、MySQLにcompare
テーブルの値の一意の組み合わせのみを許可するように強制する必要があります。
たとえば、compare
テーブルに次の行があるとします。
id_1 | id_2
------------
1 | 2
MySQLに次の行を挿入させないようにしたいのですが。
id_1 | id_2
------------
2 | 1
MySQLに1,2
または2,1
両方ではありません。
10.2.14-MariaDBを使用しています-MariaDBサーバー
MariaDB 10.2を使用しているため、CHECK
制約を追加して、最初のIDが2番目のID(id_1 < id_2
)よりも小さいことを強制できます。 CHECK
constraint はバージョン10.2.1で追加されました。
これには、INSERT
ステートメントのIDを正しい順序で指定する必要があるという制限があります((3,2)
がであっても、(2,3)
の組み合わせを挿入することはできませんいない):
ALTER TABLE compare
ADD CONSTRAINT ids_unique_combination_chk
CHECK (id_1 < id_2) ;
dbfiddle.uk でテストされています。
INSERT
ステートメントとプロシージャに手間をかけたくない場合は、2つの VIRTUAL
(またはPERSISTENT
)列 とUNIQUE
制約。
バージョン5.2以降、MariaDBで仮想列が利用可能になり、10.2.1でいくつかの制限が解除されました。
ALTER TABLE compare
ADD small_id BIGINT AS (LEAST(id_1, id_2)) VIRTUAL,
ADD big_id BIGINT AS (GREATEST(id_1, id_2)) VIRTUAL,
ADD CONSTRAINT ids_unique_combination_uq
UNIQUE (small_id, big_id);
Dbfiddle.ukでもテスト: fiddle-2 。