“一对多”关系的唯一约束(无触发)

时间:2010-04-20 21:30:12

标签: sql postgresql unique one-to-many atomicity

为了说明问题,我举了一个例子:

tag_bundle由一个或多个标签组成。   唯一标记组合可以映射到唯一的tag_bundle,反之亦然。

 tag_bundle                   tag            tag_bundle_relation
 +---------------+        +--------+      +---------------+--------+
 | tag_bundle_id |        | tag_id |      | tag_bundle_id | tag_id |
 +---------------+        +--------+      +---------------+--------+
 |       1       |        | 100    |      |       1       |  100   |
 +---------------+        +--------+      +---------------+--------+
 |       2       |        | 101    |      |       1       |  101   |
 +---------------+        +--------+      +---------------+--------+ 
                          | 102    |      |       2       |  101   |
                          +--------+      +---------------+--------+  
                                          |       2       |  102   |
                                          +---------------+--------+

不能有另一个tag_bundle具有与标签100和标签101完全相同的组合。 不能有另一个tag_bundle具有与标签101和标签102完全相同的组合。

如何在执行SQL “并发”时确保此类唯一约束!! 也就是说,防止同时添加两个完全相同标记组合的包

在任何表上添加简单的唯一约束都不起作用, 是否有除Trigger或显式锁定之外的任何解决方案。

我只采用这种简单的方式:将标签组合制作成字符串,并将其作为唯一的列。

tag_bundle  (unique on tags)         tag            tag_bundle_relation
 +---------------+-----------+      +--------+      +---------------+--------+
 | tag_bundle_id |  tags     |      | tag_id |      | tag_bundle_id | tag_id |
 +---------------+-----------+      +--------+      +---------------+--------+
 |       1       | "100,101" |      | 101    |      |       1       |  101   |
 +---------------+-----------+      +--------+      +---------------+--------+
                                    | 100    |      |       1       |  100   |
                                    +--------+      +---------------+--------+ 

但似乎不是一个好方法:(

2 个答案:

答案 0 :(得分:1)

为什么“没有触发器”的约束?有了它,结合一些数据重复,您可以得到您所需要的。将解决方案中的“标签”字段更改为INTEGER的数组字段(或任何类型的tag_id)

虽然认识到解决方案的不愉快,但我认为没有办法绕过它。虽然我会使用数组而不是字符串作为'tags',但是将它放在tag_bundle的单独表中,仍然使其唯一并在tag_bundle_relation上设置触发器以使用array_agg(tag_id)(> 8.4)更新tags字段,如果失败,则触发更新失败。

答案 1 :(得分:-1)

为了在多个交易更新表格时正常工作,您需要创建一个最终推迟的constraint trigger