| [ Prev 2. データベースを作る ] | [ Top 目次 ] | [ Next 4. 検索パターンとその実装 ] | 
FireBird/InterBase には gpre という gcc のプリプロセッサがあり、C言語から直接操作することができます。
         私が、InterBase3.0 時代から InterBase/FireBirdを愛用してきているのも、この強力で万能な gpre があることが大きな理由の一つでもあります。
そのほかに、Perl,Python,java,PHP など多くの言語がサポートされているようです。
あ、もちろん Delphi, C++Builder などの Borland製品もあります。
Python と java は、勉強不足で、よく知りません。
         PHP はどうも気持ち悪いです。
じつは、とんでもないことに!今まで個人的には CGI プログラムは C で書くことが多かったのです。
         なんというスリリングなバッファオーバーフローの恐怖との闘いの世界!
今回は常識的に Perl でやってみました。
IBPerl という、Module があります。
         作者は、Bill Karwin 氏で、GPL ライセンスです。
Red Hat 9 上での makeでは若干のパッチが必要でした。
IBPerl.pm のソースを読むと、3個のオブジェクトしかありません。
         これだけで、一通りのことはできます。
そんだけ。なんて分かりやすい!
IBPerl::Connection
    method
        new()         データベース接続
        create()      データベースの新規作成
        disconnect()  データベース切断 
    parameter
        Server        サーバ名(デフォルトはlocalhost)
        Path          データベースのPath
        Protocol      TCP/IP(デフォルト), NetBEUI, IPX/SPX
        User          ユーザー名(省略されると環境変数 ISC_USER)
        Password      パスワード(省略されると環境変数 ISC_PASSWORD)
        Dialect       1(デフォルト)または3
        Charset       NONE(デフォルト),EUCJ_0208,SJIS_0208
        Role          NONE(デフォルト)
    Return: データベースハンドル
SAMPLE:
my($DB)=IBPerl::Connection->new(Server=>"hostname.domain.tld",
                                Path=>"/DB/birds/birds.fdb",
                                User=>"SYSDBA",
                                Password=>"##########");
        
IBPerl::Transaction
    method
        new()        トランザクション開始
        commit()     コミット
        rollback()   ロールバック
    parameter
        DataBase     データベースハンドル
        Active       (ReadOnly Property)トランザクションの状態
    return           トランザクションハンドル
SAMPLE:
my($trans)=IBPerl::Transaction->new($DB)
        
IBPerl::Statement
    method:
        new()            オブジェクト生成
        execute()        SQL実行
        fetch(<line-no>) フェッチ(行番号の指定も可能)
        rollbacl()       rollback
    parameter:
        Transaction      トランザクションハンドル
        SQL              SQL文
        TimeStampFormat  TIMESTAMP型のフォーマット(strftime(3)形式)
        DateFormat       DATE型のフォーマット     (strftime(3)形式)
        TimeFormat       TIME型のフォーマット     (strftime(3)形式 dialect3)
    return               ステートメントハンドル
SAMPLE:
mt($state)=IBPerl::Statement->new(Transaction=>$trans,
                                  SQL=>"SELECT * FROM ORDERTAB");
if ($state->execute()==0){
    my(%hash);
    while ($state->fetch(\%hash)==0){
        for (keys %hash){
            print("$_=$hash{$_}\n");
        }
    }
}
        何はともあれ動かしてみよう。
ともかくデータがないことには始まりません。
         ってわけで、1.3.項のデータをデータベースに放り込むプログラムを書いてみました。
このプログラムを実行してみると、SQL*Loader (c) Oracle のようなものが不要な訳が分かると思います。
データ更新部分は、52,56,57 行の 3ステップです。
4 個のテーブルに対して、40,000 回の存在チェックとINSERT、同時に 1 個のテーブルに対してトリガーによる参照と更新、そして 23 個の INDEX の同時更新を『オンライン状態のまま』行っています。
           実験環境の古いマシンで 14 秒なので、今どきの PC サーバなら数秒(1 桁)でしょう。
参考までに、このプログラムの最後の commit を rollback に変えて、rollback 処理のみの所要時間を計測したところ、約 0.3 秒でした。 FireBird の特徴がよく分かります。
2章の最後の PROCEDURE PSGO_CHKINSERT を使っています。
さくっと、動きました。
Perl で十分に速いのですが、試しに gcc/gpre で書いてみたら約 4 秒 ( 2,500明細/秒 ) でした。
           3.5 倍の速度差。思った以上に差が開きました。
         ( オンライン状態での更新でこの速度は、他の DBMS に大きく水を空けているかもしれない。 )
IBPerl のストアードプロシジャ呼び出しのオーバーヘッドはやはり大きいようです。
         どうしても速度が欲しい時は C の出番になるかもしれません。
ただし、gpre はこのような更新系の場合は文句なしに速いのですが、SUSPEND 付の PROCEDURE を呼び出す参照の場合に限り、強制的に TCP_NODELAY ( tinygram 回避のための tcp/ip Nagle アルゴリズムを使用しないモード ) になるように見えます。
これは一長一短で、使用環境を考えないと逆効果になります。
この件に関して日本語の情報は皆無、英語の情報も不十分で、詳しくはソースを追ってみるしかなさそうですが、やりきれていません。
isql で中身を見ます。OK!
SQL> SELECT * FROM COUNTERTAB;
TABLENAME                COUNTMAX
==================== ============
ORDERTAB                       23
FAMILY                        146
GENUS                        2060
SPECIES                      9946
SQL> SELECT COUNT(*) FROM ORDERTAB;
       COUNT
============
          23
SQL> SELECT COUNT(*) FROM FAMILY;
       COUNT
============
         146
SQL> SELECT COUNT(*) FROM GENUS;
       COUNT
============
        2060
SQL> SELECT COUNT(*) FROM SPECIES;
       COUNT
============
        9946
SQL> SELECT ORDERJPN,FAMILYJPN,SPECIESJPN FROM VSPECFULL WHERE FAMILYNAME='Gaviidae';
ORDERJPN                 FAMILYJPN                                SPECIESJPN
======================== ======================================== ========================================
コウノトリ目             アビ科                                   アビ
コウノトリ目             アビ科                                   オオハム
コウノトリ目             アビ科                                   シロエリオオハム
コウノトリ目             アビ科                                   ハシグロアビ
コウノトリ目             アビ科                                   ハシジロアビ
        使えることが分かったので、本格的に使う準備です。
よく使うDB操作をサブルーチン化してみました。
これらサブルーチンをPackageにしました。
| [ Prev 2. データベースを作る ] | [ Top 目次 ] | [ Next 4. 検索パターンとその実装 ] | 
この HTML を検査する。 ( XHTML 1.0 Strict で書かれています )
          Another HTML Lint Gateway ( Mirrored by htmllint.oosato.org )