すべてのプロダクト
Search
ドキュメントセンター

PolarDB:ルールとトリガー

最終更新日:May 31, 2024

トリガーを使用して実行できる多くのことは、PostgreSQLruleシステムを使用して実装することもできます。 ルールによって実装できないものの1つは、いくつかの種類の制約、特に外部キーです。 列の値が別のテーブルに表示されない場合は、コマンドをNOTHINGに書き換える修飾ルールを配置できます。 しかし、その後、データは静かに捨てられ、それは良い考えではありません。 有効な値のチェックが必要な場合、および無効な値の場合にエラーメッセージを生成する必要がある場合は、トリガーによって実行する必要があります。

この章では、ルールを使用してビューを更新することに焦点を当てました。 この章のすべての更新ルールの例は、ビューのINSTEAD ofトリガーを使用して実装することもできます。 特に更新を実行するために複雑なロジックが必要な場合、このようなトリガーの書き込みはルールの書き込みよりも簡単です。

両方で実装できることについては、データベースの使用状況に最もよく依存します。 トリガーは、影響を受ける行ごとに1回起動されます。 ルールはクエリを変更するか、追加のクエリを生成します。 したがって、1つのステートメントで多くの行が影響を受ける場合、1つの追加コマンドを発行するルールは、すべての行に対して呼び出され、何度も何度も実行する必要があるトリガーよりも高速になる可能性があります。 ただし、トリガーアプローチは、ルールアプローチよりも概念的にはるかに単純であり、初心者にとっては簡単に理解できます。

ここでは、1つの状況でルールとトリガーの選択がどのように行われるかの例を示します。 2つのテーブルがあります。

CREATE TABLEコンピュータ (
        hostname text, -- 上限値
        manufacturer text
    );

    CREATE TABLEソフトウェア (
        ソフトウェアのテキスト, --
        hostname text-関数関数
    );

どちらのテーブルにも何千もの行があり、hostnameのインデックスは一意です。 ルールまたはトリガーは、削除されたコンピューターを参照するソフトウェアから行を削除する制約を実装する必要があります。 トリガーは次のコマンドを使用します。

DELETE FROMソフトウェアWHEREホスト名= $1;

computerから削除された個々の行ごとにトリガーが呼び出されるため、このコマンドのプランを準備して保存し、パラメーターにhostnameの値を渡すことができます。 ルールは次のように記述されます。

RULE computer_delを作成してコンピュータに削除する
        ソフトウェアWHEREホスト名=OLD.hostname; 

次に、さまざまな種類の削除を見ていきます。 aの場合:

コンピュータWHEREホスト名='mypc .local.net ';

テーブルコンピュータはインデックス (高速) でスキャンされ、トリガーによって発行されたコマンドもインデックススキャン (高速) を使用します。 ルールからの追加コマンドは次のとおりです。

ソフトウェアWHERE computerから削除します。hostname = 'mypc .local.net'
                           AND software.hostname = computer.hostname; 

適切なインデックスが設定されているため、プランナーは

Nestloop
  -> コンピューター上のcomp_hostidxを使用してインデックススキャン
  -> ソフトウェア上のsoft_hostidx
を使用してインデックススキャン

したがって、トリガーとルールの実装の間に速度にそれほど大きな違いはありません。

次の削除では、ホスト名古いで始まるすべての2000コンピュータを取り除きたいと思います。 それを行うための2つの可能なコマンドがあります。 1つは:

ホスト名>= 'old' のコンピューターから削除
                           そしてホスト名 <'ole' 

ルールによって追加されたコマンドは次のとおりです。

ソフトウェアWHERE computer.hostname >= 'old' AND computer.hostname < 'ole' から削除
                           AND software.hostname = computer.hostname; 

プランで

ハッシュ参加
      -> ソフトウェアのSeqスキャン
      ->  Hash
        -> インデックススキャンを使用してcomp_hostidxコンピューター 

他の可能なコマンドは次のとおりです。

DELETE FROM computer HERE hostname〜 '^ old';

これにより、ルールによって追加されたコマンドの次の実行計画が作成されます。

Nestloop
      -> コンピューター上のcomp_hostidxを使用してインデックススキャン
      -> ソフトウェア上のsoft_hostidx
を使用してインデックススキャン

これは、計画者が、ANDと組み合わされた複数の修飾式がある場合、コンピュータにおけるホスト名の修飾がソフトウェア上のインデックススキャンにも使用され得ることを認識していないことを示している。 このトリガは、削除しなければならない2000の古いコンピュータのそれぞれに対して1回呼び出され、その結果、コンピュータ上で1回のインデックス・スキャンが行われ、ソフトウェア上で2000回のインデックス・スキャンが行われる。 ルールの実装は、インデックスを使用する2つのコマンドで実行されます。 また、シーケンシャルスキャンの状況でルールがさらに高速になるかどうかは、テーブルソフトウェアの全体的なサイズに依存します。 すべてのインデックスブロックがすぐにキャッシュにある場合でも、トリガーからSPIマネージャーを介した2000コマンドの実行には時間がかかります。

最後に見たコマンドは次のとおりです。

DELETE FROM computer WHERE manufacturer = 'bim';

この場合も、多くの行がコンピュータから削除されることになる。 そのため、トリガーはエグゼキュータを介して再び多くのコマンドを実行します。 ルールによって生成されるコマンドは次のとおりです。

ソフトウェアWHERE computer.manufacturer = 'bim' から削除
                           AND software.hostname = computer.hostname; 

このコマンドの計画も、2つのインデックススキャンでネストされたループになり、コンピューターで異なるインデックスを使用するだけです。

Nestloop
      -> コンピューター上のcomp_manufidxを使用してインデックススキャン
      -> ソフトウェア上のsoft_hostidx
を使用してインデックススキャン

これらの場合のいずれにおいても、ルールシステムからの余分なコマンドは、コマンド内の影響を受ける行の数から多かれ少なかれ独立している。

要約すると、ルールは、それらのアクションが大きくて資格の悪い参加をもたらした場合、プランナーが失敗する状況でのみ、トリガーよりも大幅に遅くなります。