这是我试图实现的目标:
我有一个表fabric
包含用于构建产品的结构。当管理员记录新结构时,他可以定义是否可以使用另一个结构选择此结构(用于材料的兼容性)。
这种排斥关系是可交换的。如果X不与Y一起使用,则意味着Y不能与X一起使用。
为了实现这一点,我创建了一个表fabric_exclusion
,其中包含两个字段(id_fabric1
和id_fabric2
),形成一个主键。
但是如何让CRUD操作使用这个底层逻辑(id_fabric1=X|id_fabric2=Y) = (id_fabric1=Y|id_fabric2=X)
?
更新:以下是我的尝试:
CREATE TABLE IF NOT EXISTS `PREFIX_fabric_exclusion` (
`id_fabric1` INT(10) NOT NULL,
`id_fabric2` INT(10) NOT NULL,
CONSTRAINT `ids` UNIQUE (`id_fabric1`, `id_fabric2`),
PRIMARY KEY `ids`
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
答案 0 :(得分:1)
可能有点开销,但您可以在计算字段上使用基于id_fabric1
和id_fabric2
的计算字段以及唯一约束(甚至是主键)。因此,确保例如,如果存在元组(4,3)
则不能插入元组(3,4)
,反之亦然:
CREATE TABLE `PREFIX_fabric_exclusion` (
`id_fabric1` INT(10) NOT NULL,
`id_fabric2` INT(10) NOT NULL,
combinedKey int(21) as (if (id_fabric1 < id_fabric2, id_fabric1*100000000+ id_fabric2, id_fabric2*100000000+id_fabric1)) stored primary key
)
insert into PREFIX_fabric_exclusion(id_fabric1, id_fabric2) values (3, 4);
insert into PREFIX_fabric_exclusion(id_fabric1, id_fabric2) values (4, 3); # Error: Duplicate entry '300000004' for key 'PRIMARY'
答案 1 :(得分:1)
我知道我可能已经迟到了。当我摸不着头脑时,我找到了一个可行的解决方案来强制执行此操作。
通常,当你有这样一个交换对时,顺序并不重要。
我开始添加一个BEFORE INSERT TRIGGER。
CREATE TRIGGER `tbl_BEFORE_INSERT` BEFORE INSERT ON `thread` FOR EACH ROW
BEGIN
SET @l = least(new.id1, new.id2);
SET @l2 = greatest(new.id1, new.id2);
SET new.id1 = @l;
SET new.id2 = @m;
END;
有了这个,你总是按顺序插入,永远不必违反它。因为,它基本上将较小的一个分配给一个字段,而将较大的一个分配给另一个字段。由于它们可以保证在每一行中调用,因此您几乎可以确定完整性约束,但需要一些开销。但是,我发现另一个有趣的方法是通过配对功能再次以相同的方式,但是对于交换性,我会说,我会使用无序的配对函数,但它们不像这些那样具有空间效率。