| [ 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 )