【发布时间】:2012-02-10 14:53:47
【问题描述】:
我想在我的“标签”实体之间建立关系。这些关系是双向的,并存储在我的实体“TagRelation”中:
每个标签关系在 tag_relations 表中应该只有 1 个条目,因为关系的方向没有意义。例如,如果我插入:
“森林”(标签 1)“树”(标签 2)
我应该不可能以相反的方式插入关系:
“树”(标签 1)“森林”(标签 2)
这是表tag_relation的SQL代码:
CREATE TABLE IF NOT EXISTS `tag_relation` (
id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`tag_id_1` INT(10) UNSIGNED NOT NULL ,
`tag_id_2` INT(10) UNSIGNED NOT NULL ,
`type` ENUM('related_subject','synonymous','alternative_writing') NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_tag_1` (`tag_id_1` ASC) ,
INDEX `fk_tag_2` (`tag_id_2` ASC) ,
UNIQUE INDEX `ux_relation_1_2` (`tag_id_1` ASC, `tag_id_2` ASC) ,
UNIQUE INDEX `ux_relation_2_1` (`tag_id_2` ASC, `tag_id_1` ASC) ,
CONSTRAINT `fk_tag_1`
FOREIGN KEY (`tag_id_1` )
REFERENCES `mm`.`tag` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tag_2`
FOREIGN KEY (`tag_id_2` )
REFERENCES `mm`.`tag` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1
现在的唯一索引不会强制执行我想要的唯一关系。如何在我的数据库中强制执行此操作?
【问题讨论】:
-
我不是专家,所以可能有更好的解决方案。但是,如果您认为 [tag1, tag2] 等于 [tag2, tag1],您可以强制执行规则,即始终在第一列中以最低 ID 插入一对,在第二列中插入最大 ID。这可以通过一个简单的检查约束来强制执行。
-
你的意思是用触发器?解决方案听起来不错。我必须找出如何编写该触发器。
-
我认为它不起作用,因为 TagRelation 实体已经设置了 tag_1 和 tag_2 引用。您建议的触发器在插入数据库时可能会扭转这些情况,从而导致 TagRelation 实体和数据库之间的不一致。但也许我可以创建一个触发器来检查数据库中是否已经存在唯一关系。
-
我不是在谈论触发器。我说的是检查约束。正确排序它们的工作将是 JPA 实体的工作。
-
我明白了。我该如何做这样的约束?
标签: sql database jpa unique relation