doc drawn up: 2006-12-16 .. 2006-12-26
「一言主」に続くデータベースシステム構築第 2 弾は、インターネットのブックマークを、ブラウザのローカルデータとして蓄積するのではなく、Web サーバ側に CGI 経由でアクセス可能なデータベースとして利用できるものにする Web Bookmark ──名付けて「Webookmark」──である。
筆者の個人的な話なのだが、Windows と Linux をデュアルブートで使い分けしていて、日常的に使っている Windows 側のブックマークが Linux 側から使えないのが不便に感じている。そこでこの際ブックマークをサーバサイド化してしまおうというのがこの「Webookmark」作成の動機である。
データベースのスキーマは以下のような設計にする:
凡例:表名(列1の名前,列2の名前,……)
(※実線は主キーを表し、破線は外部キーを表す)
書籤利用者(名前,パスワード)
CREATE TABLE BookmarkUser ( name VARCHAR(64) NOT NULL, password VARCHAR(16), PRIMARY KEY (name) );
書籤(分類,標識名,URI,所有者,優先度,備考)
CREATE TABLE Bookmark ( category VARCHAR(255), label VARCHAR(255) NOT NULL, uri VARCHAR(255) NOT NULL, owner VARCHAR(64) NOT NULL, priority SMALLINT, comment TEXT, PRIMARY KEY (uri, owner), FOREIGN KEY (owner) REFERENCES BookmarkUser (name) ON DELETE CASCADE ON UPDATE CASCADE );
標識名は個々の書籤(ブックーマーク)に標識として付ける名称。所有者はマルチユーザ仕様を視野に入れたからである。分類は、書籤をカテゴリに分けてグループ化するためのもの。優先度は、同じ分類に存在する書籤同士の並び順をコントロールするためのもの、備考は書籤に付けるコメント情報である。
E-R 図は次のようになる:

「一言主」の場合は、手元の PC の Access で実質的なデータベース管理を行い、Web サーバの MySQL 側はデータベースのコピーを読み出して表示するだけだった。だが、今回の「Webookmark」の場合はそうはいかない。ブックマークを参照できるだけでなく、いつでも好きな時に新しいブックマークを加えたりして随時更新可能なシステムにしなければならない。すなわち、データの蓄積・更新・参照の全過程にわたって Web サーバの MySQL 側で管理する態勢になる。
MySQL でデータベースを管理する場合、重要な注意点は「現時点(v5.1)では、MySQL には外部キーに関する機能が標準(MyISAM エンジン)では実装されていない」ということである。すなわち、データベースエンジン側では外部キーの整合性制約の面倒を見てくれないので、CGI プログラムの側でその穴をカバーする必要がある。
表の新規作成については、既に作成した「DBMS ゲートウェイ」を使った。
書籤表は、「所有者」が外部キーとなっているので、レコードを追加する場合には、整合性制約に配慮しなければならない。「所有者」フィールドの入力については、プルダウンメニュー方式で必ず書籤利用者表に存在する名前の中から選択させるように、ユーザインタフェース上での制約を課すようにした。
一方、レコードの削除については、整合性制約に配慮する必要はないので、特に問題はない(普通に DELETE 命令を使う)。
表の新規作成については、既に作成した「DBMS ゲートウェイ」を使った。
書籤利用者表の場合は、外部キーは存在しないので、レコードの追加に関しては単純に INSERT 命令を Perl/DBI で実装すればいい。問題は、削除の場合である。
書籤利用者表の「名前」は、ブックマーク表の「所有者」の被参照キーなので、整合性制約を考える必要がある。今回のシステムでは、カスケード型の削除時制約とすることにした。すなわち、書籤利用者表の「名前」を削除すると、対応する書籤表のレコードがすべて連鎖削除される。一方、書籤利用者表の「名前」の更新機能は設けないので、更新時制約については特に考えないことにした。
よって、書籤利用者表のレコードを削除(DELETE FROM BookmarkUser WHERE user=XXX)する際には、同じ「名前」を「所有者」とする書籤表のレコードをすべて削除する SQL 命令(DELETE FROM Bookmark WHERE owner=XXX)の実行を併せて行う仕様にした。
以上のデータベース仕様に基づいて、Webookmark を完成させることができた。実際のプログラミングにおいては、データベース設計の面よりも、CGI プログラムとしてのユーザインタフェースの面での試行錯誤が多かったが、その辺りのことは本稿では主題から外れるので割愛する。
参考までに、実際に当サイトで稼働している Webookmark システムにゲスト用アカウントを設けておいたので、試用していただいて構わない。
実際には筆者は、この Webookmark を(ログイン済みの状態が)ブラウザのデフォルトページになるように設定し、HTML のフレーム技術と組み合わせて利用している。今は、IE のブックマークを「Webookmark」用の CSV に変換するスクリプトを作成したので、それを使って全ブックマークを Webookmark 化しつつあるところである。
mihr.net::comp::lang::DB