1

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

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 列索引限制(我想了解决第二个问题的方法,但仍然),我必须限制组中的行数。
  2. 在 B_ID 的组合上创建一些唯一的哈希值并使其唯一。也许我还不够数学家,但我想不出一种不限制我可以用于 B_ID 的值数量的方法。

我觉得我在这里遗漏了一些明显的东西,比如我可以添加某种排序列并设置不同的唯一键,但我已经做了很多阅读并且没有想出任何东西。也可能是我继承的数据模型有缺陷,但我想不出任何能给我类似灵活性的东西。

4

1 回答 1

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
于 2011-03-18T01:08:49.660 回答