2

Oracle 11g データベースには、主キー I_Node (int) と、同じテーブル内の別のレコードを参照する I_Parent_Node (int) という列を持つテーブルがあります。ルート ノードは I_Parent_Node = null です。このようにして、ノード、リーフ、ブランチなど、呼びたい名前のツリー構造を形成します。

多くの場合、ノードのブランチ全体、つまりノードとそのすべての子を一度に削除する必要があります。場合によっては、50,000 件以上など、非常に多くのレコードがあります。自己参照テーブルではカスケード削除が許可されていないため、葉から始めてツリーを遡って 1 つずつ削除する必要があります。数時間の削除時間が発生しました。

別のプログラムがオフピーク時に削除のマークが付けられたノードを一掃する「削除のマーク」手法を実行することを検討していますが、データベース設計の変更またはその他の Oracle 構造がここで役立つかどうかに興味があります。仕事で学んだことを除けば、私は Oracle のトレーニングを受けていません。また、データベースを作成した人々は、それほど大量のことを念頭に置いていませんでした。データベースの設計はまだ固定されていないため、変更を受け入れます。

4

3 に答える 3

1

階層構造をメインテーブルから分離することを検討することをお勧めします。したがって、メインテーブルにはプライマリID(「ID」と呼びます)があり、階層テーブルには「ID、ParentID、TreeID」があります。ParentIDはそのIDの親ノードであり、TreeIDはツリー(レベル1)の最上位の親です。

したがって、レベル1ノードは次のようになります。

ID, ParentID, TreeID 
1, [null], 1

レベル2ノードは次のようになります。

ID, ParentID, TreeID
2, 1, 1

レベル3ノードは次のようになります。

ID, ParentID, TreeID
3, 2, 1

等々。

Oracle階層クエリ(クエリによる接続)を使用して、ツリーをクエリまたはトラバースします。このテーブルは非常に薄いため(列は多くなく、これらの3 +いくつかの変更された日付である可能性があります)、これらの関係の更新は、メインテーブルをいじるよりもはるかに高速でスケーリングが優れているはずです。

于 2012-04-10T18:56:18.410 に答える
1

これは、遅延可能な制約と階層クエリを使用して実行できるはずです。

外部キー制約 (I_Parent_Node 上の) がまだ遅延可能でない場合は、それを削除し、キーワード「DEFERRABLE」を使用して再作成します。

これは、Oracle の例の EMPLOYEES テーブルを使用した例です (これが実行されるように DEPARTMENTS テーブルも変更しましたが、実際には例には必要ありません)。

現在延期できない場合は、外部キーを削除して再作成します。

alter table employees drop constraint emp_manager_fk;
alter table employees add constraint emp_manager_fk foreign key (manager_id) references employees(employee_id) deferrable;

トランザクションで、制約を延期し、階層クエリを使用して削除します。

set constraints all deferred; 

delete
from     employees e
where    employee_id in (select   employee_id
                         from     employees
                         start with employee_id = 108
                         connect by prior employee_id = manager_id);

「108」は私の「親」レコードの ID です。

于 2012-04-10T21:05:01.880 に答える
0

すでに標準的なチューニングを行っていると思います。つまり、ノードと親ノードの ID 列は適切にインデックス化されていますか?

(1) この問題へのアプローチの 1 つは、PL/SQL を使用することです。最初にリーフ行を返す階層クエリを使用して、削除する ID を配列に一括収集します。次に、配列を使用して一括削除 (FORALL) を実行します。

(2) もう 1 つのアプローチはソフト削除です。行を「削除済み」としてマークしますが、実際には削除しないでください。アプリケーションを変更する必要があります(またはOracle VPDを使用して、「削除された」行を問合せから自動的に除外します)。ノードの削除が比較的まれな場合、これはかなりうまく機能する可能性があります。しかし、定期的に多くのノードを削除している場合、テーブルが古いデータでいっぱいになってしまいます。

于 2012-04-11T02:25:49.297 に答える