9

私は言うテーブルを持っています:

CREATE TABLE "DataNode" (
   "ID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 );

 CREATE TABLE "DataNode_Revisions" (
   "ID" NUMBER(7,0),
   "NODEID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 ) COMPRESS;

だから私はこれらの2つのテーブルを持っています。「DataNode」からすべての読み取りを行い、変更が発生すると、現在のエントリを「DataNode_Revisions」に書き出し、既存の「DataNode」レコードを変更します。理にかなっていますか?

これが最善の方法ですか?スキーマが変更されたときに問題が発生することはすでにわかっています。私はより良い代替手段を見つけていませんが、もしあれば教えてください! これをすべて1つのテーブルに保持すると、パフォーマンスが大幅に低下すると思いますか? つまり、レコードの数を 4 倍以上にすることになり、すでにかなりの数があります。Drupal はノードのリビジョンをこのように保存していると思いますが、それによってパフォーマンスの問題が発生しないことに興味があります。

「DataNode」は常に多くのユーザーに読まれています。ただし、書き込みはほとんど発生しません。「DataNode_Revisions」は、たまにしか読み取られません。私は非常に多くのテーブルを維持することを心配しています。「DataNode」は、これに非常によく似た ~25 のテーブルの 1 つです。

4

4 に答える 4

6

古い行を DataNode テーブルに格納することによるパフォーマンスへの影響があるかどうかは、DataNode 行へのアクセス方法によって異なります。読み取りが現在の行のすべての単一行ルックアップである場合、テーブル内の行数は比較的重要ではありません。特定の ID の現在の行を見つけるのに、行を取得するよりも多くの作業が必要になることはありません。現在の DataNode テーブルからその ID を取得します (ここでは、ID がテーブルのキーであると想定しています)。一方、DataNode テーブルのテーブル スキャンを実行するクエリが多数ある場合、行数を 4 倍にすると、それらのクエリの実行に必要な時間が増加します。

過去の行を DataNode テーブルに配置するパスをたどりたい場合は、おそらく、現在の行が NULL で、期限切れの行が取り込まれた EXPIRATION_DATE 列を追加することをお勧めします。次に、EXPIRATION_DATE に基づいて、現在の行のみのデータを持つ関数ベースのインデックスを作成できます。

CREATE INDEX idx_current_ids
    ON DataNode( (CASE WHEN expiration_date IS NULL THEN id ELSE null END) );

次のようなクエリで使用されます

SELECT *
  FROM DataNode
 WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>>

明らかに、現在の行が必要になるたびにビューを書き換えるのではなく、この条件を持つビューを作成したいでしょう。

CREATE VIEW CurrentDataNode
AS
SELECT (CASE WHEN expiration_date IS NULL THEN id ELSE null END) id,
       type,
       name,
       status
  FROM DataNode;

SELECT *
  FROM CurrentDataNode
 WHERE id = <<some value>>
于 2010-11-23T16:35:22.173 に答える
5

私は通常、トリガーを使用して「リビジョン」テーブルへの書き込みを行います。はい、スキーマの変更により、ミラー テーブルとトリガー/アーカイブ機能を更新する必要があります。

すべての履歴と現在のリビジョンを 1 つの表にまとめておくと後悔すると思いますが、その考えは正しいと思います。

トランザクション テーブルごとにミラー テーブルを必要としない一般的なソリューションを考え出す場合は、レコードを XML に変換して clob に格納するリビジョン テーブルを 1 つだけ持つことを検討してください。 . 頻繁に、またはすばやくアクセスする必要がある場合はあまり役に立ちませんが、本当にすべてをアーカイブしたい場合には適しています。

于 2010-11-23T16:28:58.013 に答える
2

いくつかのオプションがあります。データの変更を追跡することを強制するビジネス要件は何ですか?

  • 変更を「短い」期間だけ保持する必要がある場合は、フラッシュバッククエリを使用してUNDOからデータを読み取ることができます。タイムスタンプ(bla)の時点でテーブルから*を選択します。

  • この情報を長期間保持する必要がある場合は、OracleTotalRecallと呼ばれる機能を確認してください。フラッシュバッククエリと同じように動作しますが、変更を無期限に保持します。

  • より単純なものが必要な場合は、アプリに「古い」バージョンの行を挿入させないでください。データを設定するトリガーを使用します。

  • システムが非常にビジーな場合は、「キュー」として使用する中間テーブルを使用して、2つのテーブルを分離できます。

于 2010-11-23T16:30:02.287 に答える
2

アプリケーションによって異なります。11gを使用している場合は、新しいフラッシュバックデータアーカイブを確認することをお勧めします。私は、すべての財務データやその他の重要なデータの履歴を保持するために、それを調べ始めたところです。

于 2010-11-23T16:30:02.257 に答える