没有pivot的行之间的声明完整性约束

时间:2011-03-18 00:47:09

标签: oracle data-modeling declarative integrity

我遇到类似以下连接表的情况:

A_ID  B_ID
1     27
1     314
1     5

我需要在表上设置一个约束,以防止输入重复的组。换句话说:

A_ID  B_ID
2     27
2     314
2     5

应该失败,但是

A_ID  B_ID
3     27
3     314

应该成功,因为它是一个独特的群体。

我想到的两种方式是:

  1. 根据订单在物化大小视图中旋转表格,并在枢轴字段上放置一个唯一键。我不喜欢这个,因为在Oracle中我必须限制组中的行数,因为两个转向规则和32列索引限制(考虑到解决第二个问题的方法,但仍然如此)。 LI>
  2. 在B_ID的组合上创建一些唯一的哈希值,并使其唯一。也许我不够数学家,但我想不出一种方法可以做到这一点,不会限制我可以用于B_ID的值的数量。
  3. 我觉得这里有一些显而易见的东西,比如我可以添加某种排序列并设置一个不同的唯一键,但我已经做了很多阅读而没有想出来任何东西。也许我继承的数据模型存在缺陷,但我无法想到任何会给我类似灵活性的东西。

1 个答案:

答案 0 :(得分:2)

首先,常规约束不起作用。

如果存在A_ID为1的集合,然后会话1插入A_ID 2且B_ID为27的记录,会话2插入(2,314)和会话3插入(2,5),那么这些都不会看到冲突导致约束违规。触发器也不起作用。同样,如果一个集合存在(6,99),那么另一个会话很难创建一个新的集合(6,99,300)。

带有'提交时刷新'的MV可以工作,防止上一个会话成功提交。我会更多地考虑散列选项,总结每个A_ID的散列B_ID

select table_name, sum(ora_hash(column_id)), count(*)
from user_tab_columns
group by table_name

虽然哈希冲突是可能的,但它们不太可能。

如果您使用的是11g,请查看LISTAGG。

select table_name, listagg(column_id||':') within group (order by column_id) 
from user_tab_columns
group by table_name