実践 クライアント/サーバーデータベースソリューション 第20回 第22回

第21回
データベースを巡るさまざまな疑問

Access,VB6,Jetデータベースエンジンを利用した
C/Sシステム構築に関する考察,実験および実践



秋月巌ソリューション事務所
秋月 巌 AKIZUKI,Iwao



Access 2000でデータ連結ができない!

 さて、前回はAccess 2000をVisual BasicプログラミングツールとしてのAccess 2000の可能性について検討した。そして、素性がよいというわけではないが、データベースクライアントとしては使えるだろうというところまで説明した。
 私は早速、Accesss 2000のフォームにHyper SQL DB Client Libraryを配置し、OLEDB用のDBGridコントールに連結しようと試みた。当然、DBGridコントロールのDataSourceプロパティに、Hyper SQL DB Client LibraryのRecordsetコントロールを指定する必要がある。しかし、DBGridコントロールのプロパティリストにDataSourceプロパティが表われないのである。もちろん、Visual Basic 6.0で使用する場合には、DataSourceプロパティを使用することができる。ちなみに、このコントロールをInternet Explorerに配置した場合も、DataSourceプロパティを使用することはできなかった。
 ならば、MSFlexGridコントロールを連結すればよいのではないか。しかし、MSFlexGridコントロールはADOに対応しておらず、データコントロールかリモートデータコントロールにしか対応していない。

Internet Explorerもまた…

 推測できるのは、Access2000もInternet ExplorerもADOのデータ連結に対応していないらしいということである。
 またVisual Basic 5.0環境でどのようになるかも興味があったが、Visual Basic 5.0には、OLEDB用のDBGridが添付していないため試さなかった。理由は、Visual Basic 6.0をインストールしてからアンインストールし、それからVisual Basic 5.0をインストールすればテストは可能だったが、その環境でテストすることにどれだけ意味があるかわからなかったことと、ライセンス上の問題がありそうだったことである。OLEDB用のDBGridはVisual Basic 6.0ユーザーにライセンスされているのであり、Visual Basic 5.0ユーザーにはライセンスされていないはずである。もちろん、実行用のインストールをしただけでは、デザインライセンスがないため、プログラミングをすることはできない。

データ連結は重要なのか?

 もちろん、データ連結が常に重要だというわけではない。日本のプログラマは、どちらかといえば、データ連結は使わないという方向でプログラミングしているように思える。私も同じ方針である。しかし、データ連結の便利な点も認めざるを得ないし、愚かにもMicrosoftはデータ連結を標準とするようなプログラミングスタイルを推進しようとしている。Webアプリケーションにもデータ連結をもちこもうとした(そして失敗した)Visual InterDevをみてもそれがわかる。そのような流れの中で、データ連結を使用しないというプログラマの姿勢は大切だと思うが、提供されるコンポーネントがデータ連結もできないというのは問題がある。結局、Hyper SQL DB Client LibraryがAccessでデータ連結できないならば、それはHyper SQL DB Client LibraryがAccessに対応していないということを意味する。
 今まで何度も新しい方針をたてては挫折したという過ちを、ここで再び繰り返してしまい、大変恐縮である。次号では編集部とも相談し、新しい方向性で再チャレンジしたい。

Jetデータベースエンジンのロックメカニズム

 ところで、最近、私はデータベースに関連して気になる記事をいくつか目にした。
 まず、本誌先月号の初音玲氏の記事、『パケットで知るデータベース』に注目したい。彼はJetデータベースエンジンや各種ミドルウェアを使ってOracleデータベースにアクセスする際にやりとりされるパケットをキャプチャして、データベースアクセスの動作を解析している。彼はldbファイルを使ったロックメカニズムに対して不安を感じ、それに対して何かしらの対策をすることを呼びかけている。私はこの記事を読んで、Jetデータベースエンジンのロックの方式があまりにも簡単な仕組みに依存していることに驚き、そしてこれだけシンプルな仕組みなら、かえってちゃんと動くのではないかと思ったのである。

最初は当然のメッセージが表示された

 ところで、私は本誌に連載している「SQL Server解体新書」の原稿をワードプロセッサではなく、Microsoft Access 97のデータベースで執筆している。各テストTipsをひとつのレコードとしてAccess 97のフォームに入力しているのである。この原稿を書いている前日の段階で、私は「SQL Server解体新書」を書いていたのだが、すでに編集部が指定するデッドラインは過ぎていた。私は新しいレコードにテストTipsを追記し、今までに書いた部分の修正箇所を妻に指示した。断っておくが、私はAccessのロック機構など信じたこともないし、また、疑ったこともなかった。こんなことを、しかも、締切り直前の原稿のような大切なデータを使ってやるのは、初めてなのだ。その直前に初音氏の記事を読んでいたこともあり、ちょっといたずら心があったことも確かである。それに、まさか問題があるにしても、20数レコードしかないデータベースで問題がおきるとは考えもしなかった。
 それでもひとつのテーブルをふたりで共有し操作するのはワープロでは難しいことだし、さすが、データベースは便利だなぁ、と感心して使っていた。妻は作業を順調にすすめ、いつの間にか私が操作しているレコードも修正を開始していた。私はそれを知らず操作を終了し、レコードを移動しようとした。
 そのときの画面を再現したのが、図1である。レコードが競合していたことに私はそのときに気づいた。しかし、何も慌てることはない。ただのレコードの競合だ。初音氏が解析したようなシンプルなロックメカニズムをもつJetデータベースエンジンである。妻の行なった処理は、大した作業量ではない。どちらの作業内容を生かすかのメッセージボックスも出ているし、私の作業内容を反映し、妻が修正をやり直せばよいのだ。私は迷わず「レコードの保存」ボタンをクリックした。

図1:競合したレコードを編集し、レコードを移動しようとしたときの画面
図1:競合したレコードを編集し、レコードを移動しようとしたときの画面

私はJetデータベースエンジンを信じていた…そして裏切り

 この操作の最中で競合に気づいた妻は手を止めているし、それにそもそも20数レコードしかないテーブルなのだ。こんなテスト環境のような状況で、微妙なタイミングで処理に失敗するという可能性もないはずだ。しかし、次に私の目に現われたのは図2のダイアログボックスである。よくわからないが[OK]ボタンと[ヘルプ]ボタンしかないのでは、[OK]ボタンをクリックするしかあるまい。しかし[OK]ボタンをクリックしても、しばらくすると同じダイアログボックスが表示されてしまう。そして、それを繰り返すごとに図2のAccessフォームのテキストボックスに表示されているように「#Error」の文字が現われるではないか。
 ちょっと問題があるようだけど、再起動すれば直るんじゃないかなとか思って再起動しても事態は変わらない。そのレコードを表示すると同じダイアログボックスが表示され、しかも、フォームを使用せずに直接テーブルの内容を参照しても#Errorという文字列しか現われない。結局、データは復帰できず、レコードを削除するまでメッセージも消えなかった。データベースが壊れなかったのが何よりである。

図2:不穏なダイアログが表示され[OK]ボタンをクリックするたびにデータが消えていく
図2:不穏なダイアログが表示され[OK]ボタンをクリックするたびにデータが消えていく

どこまで疑うべきなのか…

 後から考えてみると、#Errorになった項目は、ふたりが書き換えていたフィールドだった。競合の解決に失敗したとかそういうレベルの問題ではなく、両方が入力したデータも既存のデータも飛ばしてしまったのである。
 私はMicrosoftの製品と懐疑的に接するように心がけてるが、それでもまだ甘いということなのだろうか。もっとも、この問題はロック機構のアーキテクチャ上の問題というよりも、その実装方法に問題があったという気がする。いずれにしても、初音氏が指定するように競合時に何かしらの対策を施す必要があるだろう。少なくとも、Access 97のフォームを実装しているデータ共有方法が、間違い(あるいは障害)であることは疑えない。標準的な方法で作成したフォームを標準的に使用し、それでデータを失うというのはデータベースシステムとしては根本的な問題である。

無料のプロダクトは配布可能プロダクトの違い

 さて、先月号の本誌ではMicrosoft Database Engine(MSDE)を扱った記事がふたつ掲載されている。MSDEについては、本稿でも何度かとりあげてきた。MSDEはアプリケーションにバンドルして配布することが可能であり、これらふたつの記事も、それを前提に執筆されている。
 同じ無料でも配布可能かどうかというのは、大きな問題である。たとえばWindows NT Option Packは、Windows NTユーザーは無料で使用できるが、勝手に配布できるわけではない。あるアプリケーションベンダーがWindows NT Option Packが必要な製品を配給する場合、ユーザーにWindows NT Option Packを入手してもらわねばならない。これはアプリケーションの配布における統一性(この問題をもっとも明確に示しているのはLinuxのディストリビューションベンダーの存在である)を大きく損なう要因となり得る。

ライセンスの解釈は微妙

 ところで、MSDEのライセンス規約には次のように記述されている

お客様は、お客様のソフトウェア製品を設計、開発、およびテストするためにのみ、以下のことを行なうことができます。

そして、この後にはいくつかの使用形態が記述されている。私はこの文章を読んだとき、MSDEの再配布はこれらの目的でしか使用できないのかと思った。つまり、実務として運用はすることは禁止だという意味である。しかし、再配布については別途記述されている。汎用のワープロ、表計算、データベース管理ソフトウェアなどに添付して再配布することを禁止していることを除けば、とくに注意すべき条項はない。常識的な内容ばかりである。
 どうやら、再配布先のユーザーは、ここでいうお客様には入らないらしい。つまり、MSDEの配布権をもつユーザー(Visual StudioユーザーとOffice 2000 DeveloperEditionユーザー)は実運用することは禁止だが、彼らが再配布したアプリケーションを使用するユーザーは、それを使用することができる。この場合、当然バンドルしているアプリケーションから使用する場合のみに限定されるのだろう。規約にはそのように記述されていないが、汎用のワープロ、表計算、データベース管理ソフトウェアなどへのバンドルが禁止という条項を厳密に守るとそのような結果になる。

配布されないと運用できない?

 ここで気になるのは、ある会社のシステム室が社内向けに開発したシステムを、社内で運用できないと解釈できることである。この場合、部署間で配布したという解釈が成り立つのかどうかはよくわからない。もちろん、クライアントがAccess 2000だった場合は、Access 2000自身にMSDEのライセンスが含まれているので問題はない。
 しかし、Visual Basicで作ったアプリケーションでMSDEにアクセスする社内システムを開発しようというユーザーもいるだろう。その場合、やはりライセンス内容を明確にしておく必要があるだろう。一番恐いのは、曖昧な条文を記述してわざとライセンス違反を見逃し、それとは無関係な問題で利害が絡んだ場合に、ライセンス違反を名目に裁判を起こされることである。
 ライセンスは神聖なものであり、厳守されるべきものであるということも含めて、配布するプログラムのライセンス内容を正しく把握する姿勢が、無償で利用できるプロダクトを使う開発者には必要になる。

DAOだっていいのか、あるいはDAOの方がいいのか

 そして、本誌の先月号から川村浩也氏の短期集中連載『DAOだっていいじゃない』がはじまった。私はこのタイトルを見たとき、直感的にADOと比較してDAOだって、Jetデータベースエンジンへのアクセスには(の方が)いいじゃない、という内容なのだと思った。しかし、実際にはDAOのほうがRDOよりも、特定のデータベースに依存しないシステムの構築に向いているという内容である。しかも、内容を読んでいると、DAOの優位点(というよりもRDOの問題点)が解説されおり、どちらかというと「DAOだっていいじゃないか」というよりも「DAOの方がいいじゃないか」といった内容である。

誰も推薦しない方法

 DAOによるクライアント/サーバーシステムの開発には多くの問題点があるが、それを熟知している川村氏の書く記事だけに今後が楽しみである。また、現在のトレンドであるLinux+フリーDBへの接続に、DAOのような低レベルのDBMSの動作を基準にしている方法は有効だ、という意見も卓見である。私は考えもしなかったが、その通りだと思う。
 最終的に結果がどうなるかはともかく、どのベンダーも、そしてどのジャーナリズムも推薦していない方法の優位点を実証的に証明しようという姿勢を私は尊敬する。少なくとも、物議をかもすような内容になることを期待したい。
 RDOのカーソルドライバ、カーソルタイプ、そしてロックタイプの組み合わせの可否についてのレポートも強力である。その結果、証明された特定の組み合わせで指定したキーセットカーソルや動的カーソルが、自動的に静的カーソルに変更される事実は、すでに十分にスキャンダラスな内容である。

ADOはイントラネットで利点があるのだろうか?

 ただ、ADOの利点がイントラネットを対象にした場合にあるというくだりの部分の解説には、納得できないものがあった。要約すると、「ADOだとCOMをベースにしているのでイントラネットで使用することができ、そのため分散処理が可能であるが、ActiveXドキュメントEXEで実装するとリソースを大量消費するから実用性に疑問が残る」ということだが、やや意味不明である。
 ADOはデビュー時に、Active Server Pagesにバンドルされていたが、Active Server PagesはとくにADOに依存するものではない。ADOはフリースレッドモデルのコンポーネントなので、サーバー側でマルチインスタンスを実現するのに有利な点もあるとはいえ、それはイントラネットで使ううえでの決定的な理由にはならない。また、RDSの存在を除けば、ADOがとくに分散処理をするうえで有利だというわけではない(この点でもフリースレッドモデルであることは、やや有利に働く)。ただ、RDSはすばらしいメカニズムであり、川村氏がこの存在を前提にこの意見を唱えたことも考えられる。というのは、その次にActiveXドキュメントEXEの話をもち出しているのは、RDSの使用を前提としているようにも見受けられるからである。
 MicrosoftはRDSをWeb技術として前面に押しているが、これはあくまでもCOMベースのサーバーとクライアント間のレコードセットレプリケーション機構である。サーバー側にはMicrosoftのWebサーバーが必要だが、クライアントはWebに依存するものではない。実際、私はRDS(当時ADCと呼ばれていた)を使用したVisual Basicアプリケーションを作成し、ユーザーにデモをしたことがある。もちろん、httpポートを使用するため、WebベースでもクライアントがCOMに対応するInternet Explorerからも使用できるので、イントラネットに対応しているといえる。

ActiveXドキュメントが駄目でも、ActiveX.EXEがある

 そして、ActiveXドキュメントEXEのリソース問題は、Internet Explorerのベージキャッシュのクセも含めて問題はあるが、それを理由にイントラネットの実用性に疑問を投げかけるのは解せないものがある。川村氏は私と同様、都合が悪いものがあるならばそれを使用せずに、都合の良いものだけ使用しようという姿勢があると思うからである。
 私が、ActiveXドキュメントEXEの将来性に期待していたころ、その内部評価に詳しい友人は、ActiveXドキュメントの将来性のなさを私に忠告した。私はその言葉を鵜呑みにせずに評価を続けていたが、川村氏が指摘するリソースの消費問題として断念した。結局、私は『Windows NT World』99年11月号(IDGコミュニケーションズ刊)掲載の拙稿、「最先端のWebアプリケーション構築テクニック」で紹介したようにActiveX.EXEを使用する方法で目的を実現した。この方法は私の事務所が販売するプロダクトにも採用している。ただしActiveX.EXEは、Webベースで動作するが、ブラウザ内でのフォームの表示はできない。その場合はActiveXコントロールを使用することになるだろう。
 要するに、ADOは別にイントラネット環境においても、とくにアドバンテージがあるわけではないということを言いたいのである。ただ、私が好んでADOをイントラネットアプリケーションで使用してきたのは、便利なところにADOがあったからだというだけのなのである。

データベースが不安定になる理由

 さて、他人の記事に関連する内容ばかり書いてきたが、さらにもうひとつ。今度は本誌ではなく、『INTEROP MAGAZINE』99年11月号(ソフトバンクパブリッシング刊)に掲載された中本浩之氏の連載記事「データベース、生かすも殺すもコレ次第」である。第5回の今回は「データベースが不安定になる理由」である。「データベースが不安定になる理由」とは興味深いサブタイトルではないか。私はこの雑誌を毎号読んでいるわけではないので、連載の流れを理解しているわけではないのだが、LANを使ったデータベースの活用方法が解説されている。データベースというのは、Microsoft SQL ServerやOracleのようなデータベースサーバーを指すのではなく、Jetデータベースエンジンやxbaseのようなファイル共有データベースを指している。
 少し説明しておくと、私はxbaseでずい分多くのプログラムを開発してきた。最近はまったく使わないので忘れてしまったが、今でも自分がもっとも得意なプログラミング言語は、xbaseなのではないかと思う。だから、SQLデータベースのようにセット指向のデータベースよりも、ファイル共有型のレコード指向のデータベース操作の方がなじむものがある。

データが増えると不安定になる

 この記事ではデータベースがもっとも安定して動くもっとも基本的な状態は、項目がひとつでデータがひとつの状況だと説明している。そして逆に考えれば、項目やデータが多くなるほど不安定になることが想像できるという。
 データが1件というのはともかく、項目とデータが共に複数になると、プログラミング的にはデータが多くなるほど不安定になるということはあまりないはずである。しかし、直感的にこの推測は正しいように思える。それはデータベースエンジンもアプリケーションもOS上で動作するからである。データベースエンジンやアプリケーションに障害がなくても、データ件数が多くなるほど消費するメモリが大きくなり、OSのメモリマネージメントの精度が要求される。データが多くなるほど不安定になると推測されるのは、それが原因なのではないだろうか。

テーブルを小さくするためのデータ分割の効果は?

 そしてこの記事では、テーブルのサイズを小さくする方法としてテーブル分割を提案し、その検索パフォーマンスを計測している。表1はその計測結果の抜粋である。計測はAccess 2000で行ない260,808レコードあるテーブルの200,000レコード目を検索している。フィールドの数は書いてあるが、フィールドのサイズやデータの重点率は不明である。
 オリジナルにはArago for Windowsでの計測結果だとか、別の検索方法のベンチマークなどが掲載されている。xbaseをサポートするArago for Windows(私は使ったことがない)の圧倒的なパフォーマンスが印象深いが、テーブル分割のテーマとは無関係なので省略した。
 この表では同じテーブルでデータ構造を変更し、インデックスを使用しない検索時間がどのように変化するかを比較している。この結果から判断して、フィールドがひとつしかないテーブルの検索パフォーマンスは、108フィールドをもつテーブルの4.4倍に達する。

表1:『INTERROP MAGAZINE』99年11月号、「データベース、生かすも殺すもコレ次第」から抜粋
  1フィールドを持つテーブル 108フィールドを持つテーブル
200,000レコード目のデータ 76.23秒 336.16秒

最初の疑問

 私はこの結果をみて、ちょっと差が大きすぎるような気がしたのである。そう思うならば、追試するしかない。その結果が表2である。Visual Basic 5.0でコンパイルしたアプリケーションでADOとDAOの両方を計測したが、結果はほぼ同じと判断できるので、今後はADOによる計測だけを掲載する。ちなみにADOによるアクセスはODBCを経由しないネイティブのOLE DBアクセスである。

表2:テーブルの構造の違いによる検索時間の差(インデックスなし)
  1フィールドを持つテーブル
(505.2MB)
108フィールドを持つテーブル
(3.5MB)
250,000レコード目のデータ
(ADO)
3.996秒 136.236秒
250,000レコード目のデータ
(DAO)
4.006秒 132.781秒

さらに大きな差が確認される

 環境の違いや検索するレコードの位置の違い等があるため、絶対的な評価はできないが、差はさらに大きくなってしまった。34倍の差が2つのテーブルにはある。それによってシステムが安定するかどうかはともかく、テーブルのサイズを小さくすることで、インデックスを使わないときの検索パフォーマンスが、十分に改善されることは証明されたことになる。
 ここでは250,000レコードあるテーブルの最終レコードを検索している。250,000レコード目のレコードを検索しているのは、本誌本号の連載「SQL Server解体新書」とテスト条件を揃えるためである。テーブル分割は興味深いテーマなので、Microsoft SQL Serverでどのような結果になるのかに興味がある人は、「SQL Server解体新書」を併せて読んでいただきたい。Microsoft SQL Serverはベンチマークの公開が許可されていないが、Jetデータベースエンジンでは問題がない。Jetデータベースエンジンとの速度比を掲載したいところだが、それではMicrosoft SQL Serverの絶対値が計算できてしまうので、やはり、控えるべきだろう。それでも両方の条件でMicrosoft SQL Serverの方が高速だったことは報告しておく。

検索レコードの位置による差

 また、Jetデータベースエンジンで同じテーブルの200,000レコード目と250,000レコード目を検索した場合の違いを表3に掲載する。位置に比例するほどではないが、やはり、検索時間は200,000レコード目が短くなっている。

表3:200,000レコード目を検索した場合と250,000レコード目を検索場合の比較
108フィールドを持つテーブルの200,000レコード目を検索 115.11秒
108フィールドを持つテーブルの250,000レコード目を検索 136.236秒

Access 97で作成したテーブルを使用した理由

 テストではすべてのフィールドのサイズを10byteとし、テストデータはすべてのフィールドに10byteのデータを入力したものとした。テストマシンは今日の水準では貧弱なため、テスト結果の絶対値が追試のによるものの方が早いのは、マシンが理由だとは考えにくい。
 実は、このテストではJetデータベースエンジンver.4を使用したが、データベースファイルは、Access 97で作成した。このファイルはJetデータベースエンジンver.3.51がネイティブエンジンである。これには理由がある。Access 2000で作成したテーブルに先の条件でテストデータを追加していたら、170,000レコードを挿入した時点でJetデータベースエンジンの制限である2GBにファイルサイズが到達してしまい、追加できなくなったのである。ちなみに、このMDBファィルは600MBの時点で最適化を行なったが、3割程度しか圧縮できなかった。
 表1をみてもらえばわかるが、Access 97で作成したMDBファイルの場合、250,000レコードを追加しても505MBにしかならない。この差が『INTEROP MAGAZINE』誌のテストとのパフォーマンスの絶対値の差になったのではないだろうか?

でも、やつぱりインデックスが大切だ

 最後にインデックスを使用して、構造の違うテーブルの250,000レコード目にあるデータを検索した場合の結果を表4に示す。両者の差の絶対値はきわめて小さいし、何よりも分割したテーブルを検索するよりもはるかに高速である。インデックスファイルが一種のテーブルであることを考えれば、インデックスを付与することもテーブル分割の方法の一種であるということができる。しかし、効果ははるかに大きい。テーブル分割を考える前に、適切にインデックスを使用できるテーブル構造を検討する方が先だろう。

表4:テーブルの構造の違いによる検索時間の差(インデックスあり)
  1フィールドを持つテーブル
(517.2MB)
108フィールドを持つテーブル
(8.6MB)
250,000レコード目のデータ
(ADO)
0.110秒 0.07秒
250,000レコード目のデータ
(DAO)
0.101秒 0.05秒


VB Magazine ライブラリ| Visual Basic WorkGroup
int21 ホームページ| PCDN ホームページ

PCDN
Copyright (c) 1998 int21 CorporationAll Rights Reserved.
For questions or comments, please send mail to: pcdn@int21.co.jp