SQL (MySQL): 强制一行两列不同值的最佳方式?

SQL (MySQL): Best way to force different values two columns of a row?

给出以下table:

CREATE TABLE `tbl_termsynonyms` (
 `ts_term1Id` int(10) unsigned NOT NULL,
 `ts_term2Id` int(10) unsigned NOT NULL,
 PRIMARY KEY (`ts_term1Id`,`ts_term2Id`),
 KEY `fk_tbl_termSynonyms_tbl_term_t_id2` (`ts_term2Id`),
 CONSTRAINT `fk_tbl_termSynonyms_tbl_term_t_id1` FOREIGN KEY (`ts_term1Id`) REFERENCES `tbl_term` (`t_id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_tbl_termSynonyms_tbl_term_t_id2` FOREIGN KEY (`ts_term2Id`) REFERENCES `tbl_term` (`t_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

如您所见,此 table 用于在 tbl_term table.

中引用同义词

示例:table tbl_term 包含单词 "fun" 和 "joke",id 为 34 和 71,这些 ID 一起保存为一行。

现在我想阻止术语引用自身的行,例如:

71 - 71
31 - 31

是否有(SQL 方法)可以轻松实现此目的?

在 SQL 中有一个简单的方法可以做到这一点:

alter table tbl_termsynonyms add constraint chk_ts_term1Id_ts_term2Id check (ts_term1Id <> ts_term2Id);

不幸的是,MySQL 忽略了检查约束,所以这在 MySQL 中不起作用。

唉,你唯一的选择就是使用触发器。

据推测,您的数据中可以有循环 -- 所以 3 是 4 的同义词,而 4 是 3 的同义词。如果是这样的话,我看不到将术语作为同义词的真正损害他们自己。

当你想查询 table:

时,你可以将它们过滤掉
create view vw_termsynonyms as
    select ts.*
    from tbl_termsynonyms ts
    where ts_term1Id <> ts_term2Id;

您可以要求 ts_term1Id 必须小于 ts_term2Id。 MySQL 没有 CHECK 约束,因此您必须在触发器中执行。

CREATE TRIGGER MyTrigger BEFORE INSERT ON tbl_termsynonyms
FOR EACH ROW
  SET NEW.ts_term1Id = LEAST(NEW.ts_term1Id, NEW.ts_term2Id),
      NEW.ts_term2Id = GREATEST(NEW.ts_term1Id, NEW.ts_term2Id);

我还没有测试过,所以我不完全确定你可以在一个 SET 语句中完成它。您可能需要局部变量。