TOPサーバ構築・運用> 開発言語
徹底比較!! PostgreSQL vs MySQLパート2
徹底比較!! PostgreSQL vs MySQLパート2

第7回:トリガ
著者:NTTデータ   藤塚 勤也   2007/9/20
前のページ  1  2   3  4  次のページ
開発言語

   トリガの処理そのものを記述するのに使用できる言語のことです。PostgreSQLはストアドプロシージャと同様にC言語を含め、様々な言語にてトリガを作成することができます。よって、PostgreSQLのトリガでは、非常に複雑な処理を実装することも可能です。

対応SQL文の種類

   トリガを起動する対象に指定できるSQL文の種類として、PostgreSQL、MySQL共にINSERT、UPDATE、DELETEの3種類があります。

   さらにPostgreSQLは1つのトリガの起動指定に対して、この3種類のSQL文を複数指定することができます。例えば、INSERTもしくはUPDATEが実行される時に起動するトリガを指定できます。

   これに対してMySQLは、1つのトリガの指定に対して複数のSQL文を指定することはできません。このため個別の設定が必要です。

   なおリレーショナルデータベースの管理システムによっては、トリガの起動指定をSELECT文に設定できたり、「データベースへの接続時」といった条件を指定できるものがあります。


行単位/文単位

   ここでいう「行単位/文単位」は、トリガが起動する対象が「SQL文そのもの単位」なのか、それとも「対象SQL文の処理によって影響を受けた行単位なのか」の違いです。

   例えば、UPDATE文を対象とするトリガで「行単位」のケースを考えてみましょう。このケースでは、対象となるUPDATE文が3レコードを更新した場合はそのトリガは3回起動されます。文単位で設定されている場合は、1回のみ起動されます。

   PostgreSQLは、文単位/行単位ともにトリガを設定可能ですが、MySQLのトリガは行単位のみの設定となります。


BEFORE/AFTER

   「BEFORE/AFTER」は、トリガの起動が対象となるSQL文の処理の前なのか後ろなのかを指定する項目です。

   対象となるSQL文の処理の前に起動するトリガを「BEFOREトリガ」と呼び、後に起動するトリガを「AFTERトリガ」と呼びます。PostgreSQL、MySQL共にBEFORE/AFTERのどちらのトリガも設定することが可能です。


NEW・OLD演算子

   例えばUPDATE文により起動されたトリガの処理が実行中の場合、更新対象のカラムは更新する前の値と更新後の値が存在することになります。この更新前と後の値を参照するのが、この「NEW・OLD演算子」です。

   具体的には、更新前のカラムの値を参照するためにOLD演算子を、更新後の値を参照するためにNEW演算子をそれぞれ使用します。

   なおINSERT文により起動されたトリガの場合は、NEW演算子のみが有効で、DELETE文により起動されたトリガの場合は、OLD演算子のみが有効になります。

   PostgreSQL/MySQLともに、この2つの演算子をトリガの処理の中で使用することが可能です。


カスケード

   カスケードとは、あるトリガの処理により、別のトリガが起動する状況のことです。

   PostgreSQL/MySQLともに、このカスケードを抑制したり、回数を設定したりする機能はありません。このため、カスケードに注意して開発を行わないとトリガがトリガを呼び、これが永遠に継続されてしまう可能性があります。この状況への対応と問題が発生した場合の解決は、トリガの開発者に委ねられています。

   ただしMySQLでは、トリガの処理の中でトリガに関連するテーブルへの更新や挿入は行えません。このため「トリガの無限ループ」といった問題は発生しません。一方、PostgreSQLでは、トリガの処理の中でそのトリガが再度起動されるような処理も実施できるため、トリガの無限ループを作ることも可能です。


処理と定義の分離

   トリガの設定には、大きく分けて「処理部分」と「定義部分」があります。

   処理部分はトリガとして動作するために記述されたプログラムそのものです。さらに、この処理をどのSQL文に対して実行するのか、行単位なのか文単位なのか、BEFOREトリガなのかALTERトリガなのかの定義も必要です。

   このようなことから、トリガの処理部分と定義部分を分離して設定できることで、1度作成した処理を様々な定義にて使い分けることが容易に行えるというメリットが生まれます。

   PostgreSQLは、処理部分をtrigger型の返却値を持つユーザ定義関数として記述し、定義部分は「CREATE TRIGGER」文にて定義する形式になっています。このため、完全に処理部分と定義部分が分離した環境が用意されています。

   一方MySQLは、「CREATE TRIGGER」文内にて処理部分と定義部分を記述する形式になっています。つまり、そのままでは処理部分と定義部分を分離できないということになります。しかし、処理部分をストアドプロシージャによって記述しておき、CREATE TRIGGER文内の処理部分からCALL文にて、そのストアドプロシージャを呼び出す形式にすることで、処理と定義を分離することが可能となります。

前のページ  1  2   3  4  次のページ


NTTデータ  藤塚 勤也
著者プロフィール
株式会社NTTデータ   藤塚 勤也
基盤システム事業本部 オープンソース開発センタ シニアスペシャリスト。
日本タンデムコンピューターズ(現日本HP)を経て、2003年よりNTTデータにてOSS分野に参画。日頃はオリジナルOSSの開発や、OSSを用いたシステム構築への技術支援に従事。「RDBMS解剖学」(翔泳社)を共著。

INDEX
第7回:トリガ
  はじめに
開発言語
  具体的な例
  sampleの実行結果からみる処理の流れ