WebDBの構築

(last modified : 2011/04/13)
  1. WebDBとは?
  2. 準備
  3. インターフェイスプログラムの実装

WebDBとは?

PHPのページPostgreSQLのページで一部述べましたがWebDBという技術があります。これは簡単に述べるとデータベースサーバーに蓄積してあるデータをWebサーバー経由で検索、閲覧、更新、削除などを行う技術のことです。このような技術を用いると文献検索サービスや、掲示板サービスなどを簡単に作成することができます。概念図を以下に示します。

構成要素は以下の3つからなります。
  1. Webサーバー
  2. データベースサーバー
  3. インターフェイスプログラム

WebブラウザーでWebサーバー上にあるインターフェイスプログラムにアクセスすると、インターフェイスプログラムはデータベースにアクセスを行い、データベースから情報を取り出します。そして、データベースから取り出した情報をもとにHTMLを動的に作成してWebブラウザーにデータを送信するとう仕組です。

もちろんシステムを構成するに当り選択肢は様々です。WebサーバーとしてはApache,IISがあるでしょう。データベースもMySQL,PostgreSQL,Sybase,Oracleなど様々です。インターフェィスもASP,Java,Perl,PHPなどで作成するという選択支が考えられます。今回はWebサーバーとしてUnixではお馴染のApacheをデータベースとして定評のあるPostgreSQLをインターフェイスの実装にはPHPを使うことにします。Linux Red Hat,Debianでそれぞれパッケージがありインストールも簡単に行うことができます。

準備

前でも説明しましたがWebDBを構築する技術としては3つの要素(1)Webサーバー (2)データベースサーバー(3)インターフェイスプログラムに関する知識が必 要となります。ここではWebサーバーとしてApache,データベースサーバーと してPostgreSQL,インターフェイスプログラムとしてPHP3(PHP4でもほとんど 変りません)がインストールされていることを前提として話しを進めること にします。また、全てのパッケージは同一のコンピューターにインストール されていると仮定します(データベースサーバーとWebサーバーを分割する方 法は何れ述べる)。

Apacheで必要な設定

/etc/apache/httpd.conf (debian), /etc/httdp/httdp.conf (RedHat)の中で以下のものに注意しましょう。
  1. User hogehoge
  2. LoadModule php3_module /usr/lib/apache....
  3. AddType application/x-httpd-php3 .php3
  4. AddType application/x-httpd-php3-source .phps
Userはデータベースにアクセスするときの名称となるので確認しておきましょう。debianではwww-dataとなっていると思います。LoadModule, AddType はApache上でPHP3を実行するために必要なものです。この場合インターフェイスプログラムの拡張子は.php3になることに注意してください。

PostgreSQLの準備

一旦rootを経由してユーザpostgresになりましょう。postgresの状態で次のコマンドを実行します。
$ createuser hogehoge (ユーザ名はApacheで設定されているUSERと同じものにします)
Enter user's postgres ID or RETURN to use unix user ID: 1000 ->
(もしunix user IDと異る値を使う場合には数字を入力)
Is user "hogehoge" allowed to create databases (y/n)
(hogehogeは実際にデータベース作成には使わないユーザなのでnとします)
Is user "hogehoge" a superuser? (y/n)
(hogehogeは実際にデータベース作成には使わないユーザなのでnとします)
createuser: hogehoge was successfully added
(このメッセージが出たら正常にユーザは作成されたことを意味します)
今度はWebDB用のデータベースを作成しましょう。ユーザpostgresのままで例としてtestdbを作成してみましょう。
$ createdb testdb
データベースが作成されているかの確認はpsql -lコマンドで確認することができます。
datname|datdba|encoding|datpath
---------+------+--------+--------
template1|31|1|template1
testdb|1000|1|testdb
更にデータベースtestdb上にテーブルを作成しましょう。以下の例ではテーブル bookを作成し、カラム名にbookname,keyword,dateの3つを与えています。テー ブルの作成は基本的な作業なので、一般にbook.sqlなどとファイル名を付け てファイルとして保管し、テーブルを作る際にpsqlの\iコマンドの引数に book.sqlを与えて読み込ませます。book.sqlは以下のように書きます。
CREATE TABLE book (
bookname varchar(80),
keyword varchar(80),
date date
);
#psql testdbとコマンドラインから入力します。
testdb => \i book.sql
CREATE TABLE book (
bookname varchar(80),
keyword varchar(80),
date date
);
最後にユーザhogehogeに対してGRANTを行なっておきましょう。このよう にすることで、Webサーバーからデータベースにアクセスすることができる ようになります。
testdb => GRANT ALL ON book TO 'hogehoge';
これでWebサーバーApacheからデータベースサーバーPostgreSQLに接続でき る準備が整いました。以下では例を通してインターフェイスプログラムを PHP3でいかに実装するかについて触れたいと思います。

インターフェイスプログラムの実装

インターフェイスプログラムとはWebブラウザからの情報の受け付け、デー タベースサーバーへのアクセス、動的なHTML文の作成などを行うプログラム を指します。インターフェィスプログラムのデータベースとの通信部分は主 に8つの部分からなります。主な順序はデータベースとの接続、SQL文による 請求、データベースからの返答からHTML文の作成、データベースとの接続の 切断となります。以下にプログラムの流れを示します。
  1. データベースサーバーと接続する
  2. データベースサーバーと接続ができているか確認する(接続できてい れば3へ,接続できていなければエラーを返して終了)
  3. データベースサーバーにSQL文を請求する
  4. 請求したSQL文がデータベースサーバーで実行されたか確認する(実行 されたのであれば3へ,実行されなかったらエラーを返して7へ)
  5. データベースサーバーからの返答を解析する
  6. 解析した返答を元に動的にHTML文を生成しWebサーバーに出力する
  7. データベースサーバーからの返答を開放する(必要であれば3に戻る)
  8. データベースサーバーとの接続を切断する
以上に示した流れを順に追いながらプログラムの具体的なコードについて説 明していきます。
データベースサーバーと接続する
$con = pg_connect(host, port, dbname);
pg_connect() : データベースとの接続を行う関数
$con : 接続を保持する変数
$host : データベースサーバーの走っている計算機名
$port : データベースサーバーとの通信に使うポート番号
$dbhame: データベースサーバーに登録したデータベース名
データベースサーバーと接続ができているか確認する
if($con == false){
print("データベースと接続ができませんでした.");
exit;
}
データベースサーバーにSQL文を請求する
$sql = "SELECT * FROM book ORDER BY bookname;\n";
@$result = pg_exec($sql);
pg_exec($sql) : $sql文を実行する
$sql : 請求するSQL文を定義(テーブルbookの全てのローをbooknameの昇順に表示する)
$result : データベースサーバーからの結果を保持する変数
請求したSQL文がデータベースサーバーで実行されたか確認する
if($result == false){
print("SQL:\"$sql\"の実行に失敗しました\n");
exit;
}
データベースサーバーからの返答を解析する
解析した返答を元に動的にHTML文を生成しWebサーバーに出力する
$row = pg_numrows($result);
$columns = pg_numfields($result);
print("< TABLE >");
for($i = 0; $i < $columns-1; $i++){
$str = pg_fieldname($result,$i);
print("< TH > $str < /TH >\n");
}
for($j = 0; $j < $rows; $j++){
print("< TR >\n");
for($i = 0; $i < $columns-1; $i++){
$str = pg_result($result,$j,$i);
print("< TD > $str < /TD >\n");
}
print("< /TR >\n");
}
print("< /TABLE >");
pg_numrows($result) : データ数(縦)を返す関数
pg_numfields($result) : フィールド数(横)を返す関数
pg_fieldname($result,$i) : $i番目のフィールドの名称を返す関数
pg_result($result,$j,$i) : $j番目のデータの$i番目のフィールドの内容を返す関数
データベースサーバーからの返答を解放する
pg_freeresult($result);
pg_freeresult($result):データベースからの出力を解放する関数
データベースサーバーとの接続を切断する
pg_close($con);
pg_close($con):データベースサーバーとの接続を切断する関数