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

それは異なるグループであるため、成功するはずです。

私が考えた2つの方法は次のとおりです。

  1. 順序に基づいてマテリアライズ ビューでテーブルをピボットし、ピボット フィールドに一意のキーを配置します。Oracle では、ピボット ルールと 32 列のインデックス制限の両方のために、グループ内の行数を制限する必要があるため、私はこれが好きではありません (この 2 番目の問題を回避する方法はまだ考えられています)。
  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 に答える