Webアプリケーションとデータベースの接続
今日のシステム開発ではWebとデータベースの組み合わせが一般的になってきている。特にユーザーからのデータ入力を受け付けるようなシステムでは、そのインプット情報を最初からデータベースに格納しておいたほうが、ほかのシステムへの活用や検索などの点で有利である。構造的なデータベースでは苦手とされてきた全文検索の用途も、データベース製品によっては外部プログラムやオプション製品で対応しているものが増えている(MLのログなど元のデータが非構造的である場合は、全文検索にはNamazuなど専用のソフトを活用すべきであるが)。
コマースサイトでアンケート結果などをプレーンテキストでWebサーバ中に保存しておいた結果、Webサーバの運用ミスやセキュリティホールを突かれるなどして、大量の個人情報が流出するというアクシデントが時々ニュースになるのは、読者の方々も見られたことがあるだろう。これらは大量に何万件と漏れたり、そのような事実が大規模掲示板などで示されたりしたからこそニュースとして衆目にさらされることになったが、もっと小規模なアクシデントではニュースにならないし、実は情報が漏洩されていても密かに採集されているだけで、管理者が気付かないままというようなことが、水面下にはかなり多数存在する可能性がある。
このようなリスクを下げる意味でも、Webからエントリーされたデータを、別のアクセス制御機構を持つデータベースに格納して保存するのは、セキュリティ面からも有効な手段である。
では、データベースと接続可能な言語や手法について、ここで簡単に俯瞰してみよう(図8)。
【図8】Webアプリケーションとの連携 |
■スクリプト言語からの利用
WindowsのIISにおけるASPと同様に、LinuxでのメジャーなWebサーバでもHTMLから簡単に呼び出せるスクリプト言語がある。
(1)PHP
その最右翼はPHPであろう。PHPは今日多くのWebサイトで、動的なWebを作成するのに使われている。早くからデータベースとの連携機能を持っており、PHPで利用できるライブラリをデータベース側も用意している。
たとえばPHP4の場合、Postgre SQLと接続するには、pg_connectという関数を使う。
pg_connect($hostname, $port, $dbname)
PostgreSQL以外にも、ODBCを使ったデータベースアクセス用のメソッドなども用意されている。
$dsn = "odbc://LoginDB";
また、Oracleとの接続用関数も用意されている。
$dsn = ora_logon($user@tnsname, $password)
tnsnameをユーザー名と共に指定することにより、SQL*Netのクライアントで定義されたTNSNAMESを使って、任意のOracleインスタンスにアクセスすることが可能である。これを行うには、PHPを実行するWebサーバにOracleのクライアントセットがインストールされていることが必要だ。 あとは、各RDBMSごとに実行する関数は異なるが、ログオンしたデータベースに対してSQLクエリを発行し、その結果セット(カーソル)を受けとって、カーソルの最後まで表示するなり別の処理に受け渡すなりの処理を繰り返した後、データベースをクローズするというのが、一連の流れとなる。 カーソルが1件も出てこない、あるいは関数の実行結果の戻り値がFALSEならエラーとしてしかるべき処理を行うことになる。
(2)Perl
Perlは動的なWebページを作るのに最もベーシックな手法であるCGIを書く際に、最も広く用いられてきた言語である。
本来は、テキストの検索、抽出、レポート作成などのために作られた言語で、UNIX上でテキスト処理を行う際に実績のあった、AWKやSEDなどの良い点を取り込んで発展していった。これらの古典的な言語処理系に比べた改善点は、CGIやHTML、RDBMSなどへアクセスするための、モジュールと呼ばれる機能拡張がライブラリが豊富に存在し、最近ではXMLやSOAP用の拡張モジュールも作られている。一見古いタイプのCGI記述言語と見なされることも多いPerlだが、今日も進歩を続けている。また、歴史のある言語であるということは、フリーやシェアウェアの統合開発環境もいくつか準備されている。CGIを作成するために便利なモジュールも用意されており、特にLinux環境でCGIを作成するには当面主流の地位を占め続けると予想される。
Perlでデータベースアクセスを行うには、DBIというモジュールを組み込むと便利である。またOracleと接続するにはDBDというモジュールを使うと比較的容易に使用できるようになっている。これはPostgreSQLでも使用可能であるが、PostgreSQLの場合はpgsqlとPerl5以降を接続する「Pg」というモジュールも用意されている。
詳しいDBIの使用方法については、こちらなどのサイトに紹介されている。ただ、CGIとして扱うためにHTMLからの値の受け取りや、クラスの設定、モジュール読み込みなどのおまじないがPHPより多くなる傾向があるが、Perlの扱いに慣れた方にとっては、そう苦痛になるようなコーディング量でもないだろう。
■Javaからの利用
今日、本格的なWebサーバサイドアプリケーションを、LinuxまたはUNIXで運用するとなると、やはり開発言語としてはJavaを使うのが一般的となる。
Javaに関しては、サーバサイドでのみ見ても、その範囲は極めて広く、J2EE、Beans、Servlet、JSP、アプリケーションサーバ、それぞれの分野で本が1冊書けるくらいの分量になってしまう。
あえて、この少ないスペース中で概説的に記していくと、JavaそのものはJVMという仮想実行環境と、各種標準的なクラスライブラリ、コンパイラ、デバッガなどがセットになっていると思えばよい。Linux、Windowsを始め、メジャーなUNIXや各種OS上で動くJDKが用意されていて、無償でダウンロード可能であり、容易に入手可能になっている。簡単な動作の確認やコーディングなら、一般的なパソコンさえあればLinuxでもWindowsでもすぐさま実行できる。
ネットワーク接続利用やデータベースの活用、オブジェクト指向などが当たり前になってから開発された言語なので、RMIを使って特別な仕組みを用意せずともアプリケーション間通信ができるようになっているし、TCP/IPのソケット間通信の仕組みや、HTTPメソッドによる通信なども用意されている。
データベースに関してもJDBCを使うことで、RDBMS側にJDBCドライバが用意されていれば、統一的な方法でRDBMSに接続させることができる。JDBCには表2に示したような種類があるが、最近はType4が当たり前になってきている。
最後に、いくつかのキーワードを並べてこの章の終わりとしたい。
TYPE | 接続形態 |
TYPE1 | JDBC-ODBCブリッジ(実質Windows限定) |
TYPE2 | ネイティブブリッジドライバ(ベンダー固有のインタフェースに接続) |
TYPE3 | ネットプロトコルドライバ(ネットワークレベルで対応ベンダー非依存) |
TYPE4 | Javaネイティブプロトコルドライバ(JavaのみでDBに接続。ベンダー依存) |
(1)Servlet
Java対応のWebサーバ上で動作するJavaプログラム。主としてWebクライアントからのリクエストにより動作し、結果をWebクライアントに返すことになる(当然例外的な動作も可能であり、他のJavaアプリとの通信や起動、Beansの呼び出しも可能)。
ServletはServletコンテナという仕組みの上で動作するが、この仕組みを提供するのは、今日ではWebアプリケーションサーバであることが多い。
CGIと似ているが、CGIに比べて新たなプロセスを起動せず、いわゆるマルチスレッド的な動作が可能なため、大規模なアプリケーション分野でのスケーラビリティに優れている。
(2)JSP(Java Server Pages)
HTML内に、Javaのコードを記述して実行できるテクノロジー。機能的にはMicrosoft社のIISのASPに似ている。
独自のタグをHTML中に埋め込むことで、普通のHTMLコードとJSP部分を分けている。実行はJSPプロセッサが行う。HTML中に記述することでServletの問題点であった対ユーザーインターフェイスの記述の煩雑さが減少する。また、Servletと同様に、他のJavaアプリやBeansの呼び出しが可能である。
ただし、HTMLで可能な表現力の範囲内であり、JavaのSwingなどのGUIが使えるわけではない。
(3)アプリケーションサーバ
Webサーバが比較的単純なHTTPによる情報公開や、POST、GETメソッドなどによる入力処理を行っていたとすれば、アプリケーションサーバはそれからさらに進化し、Webのアプリケーションを容易に構築するための仕組みを提供するサーバ製品群である。その主な機能は、
- トランザクション管理
- Servletコンテナ、JSPプロセッサ
- オブジェクトプーリング、キャッシュ
- データベースコネクションのプーリング
- ネットワークコネクション共有
- トランザクション(セッション)管理
- 多階層化による負荷分散
- 水平分散による障害対策、負荷分散
- J2EEの提供機能サポート
などが挙げられる。
これらの機能をフル実装したアプリケーションサーバとしては、IBMのWebSphere、BEAのWebLogic、Oracle9i ASなどが有名であり、国産ベンダーも富士通のInterstage、日立のCosminexusなどがリリースされ、その多くはLinuxでも動作するようになっている。
Linuxで動作するアプリケーションサーバと言えば、Tomcatを忘れてはならないだろう。これはまだ機能的にはServlet/JSPを実行するエンジンという側面が強いが、機能強化が日々進んでいる。
通常のWeb接続はセッション管理の概念を持っておらず、複数のWeb画面間でトランザクションなどの情報を維持するには、アプリケーション側で工夫が必要となるが、アプリケーションサーバの機能を使うのもひとつの案である。
また、Tomcatの弱点を補うミドルウェアとして、国産のオープンソースソフトウェアである「Seasar」を挙げておきたい。このソフトはTomcatの弱点であるコネクションプーリングやセッション管理に特化しており、軽量なアプリケーションサーバだ。また、NazunaとXMLで記述されたビジネスルールを高速で実行できるルールエンジンを利用し、将来的にはプレゼンテーション層にはFlashの活用を考えるなど、特色あるものとなっている。
さて、駆け足でデータベースプラットフォームおよびアプリケーションプラットフォームとしてのLinuxを見てきたが、いかがだっただろうか? Linuxがインターネットサーバとしてでなく、企業の中核システムに使われるにふさわしい環境が揃い始めていることはご理解いただけけたと思う。IAサーバでシステム構築を考えるとき、もはやLinuxは外せない選択肢となりつつあるのである。
インデックスについて
【図】バイナリツリーの例 |
普通のRDBMSの場合、インデックス(索引)はバイナリツリー(Btree)と呼ばれる方式で管理される(図)。普通にデータを検索すると、そのままではすべての行を読み込まないと、条件に一致する行をすべて見つけ出すことができない。しかし、図のように、キーデータの値によって検索する範囲を絞り込んでいけばディスクI/Oの回数を大幅に減らせることになる。図では73というキー値を5回目のアクセスで見つけたが、実際にはもっと少ないディスクアクセス回数で目標を見つけられる。
この場合データの分布の範囲でバランスの採れたツリー構造とすることが最適となる。しかし多少バランスがずれても、無駄なアクセス回数は1回か2回程度増えるだけであり、全件検索に比べたら非常に効率が良いのは間違いない。
なお、インデックスは、検索時にはディスクI/O頻度を減らせるが、挿入やインデックスを張った項目に更新が生じると、インデックス自体の更新が必要となりレスポンス悪化の原因となる可能性もある。また、あまりにもインデックスのバランスが崩れた状態も好ましくないので、その影響が無視できなくなってきたときには、インデックスを一度消して再作成することもある。