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