Microsoft SQL Server入門講座:1
秋月巌 AKIZUKI, Iwao
| AccessかSQL Serverか |
|---|
クライアントとサーバーシステムは分散処理である
クライアント/サーバーシステムの時代である.コンピュータシステムに関連する多くのテクノロジーが,クライアントとサーバーという関係を築こうとしている.WebブラウザというクライアントとWebサーバーというサーバー,あるいは,ActiveXコンテナとCOMコンポーネント,それにメールサーバーとメールクライアントもクライアント/サーバーシステムである.そして,定番ともいえるのがやはり,データベースサーバーとクライアントの関係である.
これらのように処理を複数のモジュールに分割する形態のシステムは,すべてクライアント/サーバーシステムだということができる.処理を分散するのにはもちろん理由がある.大きな理由のひとつはデータをマルチユーザーで共有するための便宜を図ることであり,もうひとつは処理の負荷を分散させることでパフォーマンスの向上を狙うことである.もちろん,モジュールの共有やモジュールの管理を一元化することを目的とする場合もある.
オブジェクト指向との関係
クライアント/サーバーシステムの台頭は,コンピュータテクノロジーを席巻したオブジェクト指向とも大きく関係している.オブジェクト指向においては,多くのオブジェクトが他のオブジェクトのクライアントやサーバーになりえる.オブジェクト指向アーキテクチャが目指したのは,データの共有や負荷の分散よりもモジュールの共有だということができる.
オブジェクト指向におけるクラスの概念の説明で,クラスとは関数とデータがひとつにまとまったものという解説を見たことはないだろうか.このような観点において,データベースサーバーとはクラスの実体化したものと考えることができる.つまり,SQLという関数を用いて,データにアクセスしたり操作するオブジェクトだということができる.データベースサーバーのデータを直接操作することはできず,カプセル化されたデータを扱うには,SQL文の使用が必須になる.
SQLとデータベースサーバー
Microsoft SQL Serverの名称にSQLという文字が含まれるように,SQLがデータベースサーバーの代名詞として扱われた時期があった.SQLをサポートしているのは,サーバーデータベース製品であり,xBASEやBtrieaveのようなファイル共有型のデータベースのほとんどはSQLをサポートしていなかった.この棲みわけを破った最初のメジャーな製品はMicrosoft Access 1.1だったと記憶している.方言はあるものの十分な仕様のSQLを低価格のデータベースエンジンに統合してきたのである.その結果,SQLのサポートの有無によって,データベースサーバーとファイル共有型の区別をすることはできなくなった.
Accessもクライアント/サーバーアーキテクチャ?
ところで,Microsoft Accessのようなファイル共有型のデータベースでも,マルチユーザーにおけるデータの共有ができるのだから,それはクライアント/サーバーシステム固有のメリットではないと考えるかもしれない.しかし,ファイル共有型のデータベースも,ファイル操作のレベルにおいては,ファイルサーバーとファイルクライアントという構造になっているのである.データベースサーバーが,クライアントの要求に対して,よりインテリジェントな結果を返すのに対して,ファイル共有型の場合はディスクの読み取り結果という原始的な結果しか返さない.もっとも,一般的には,ファイル共有型のデータベースシステムをクライアント/サーバーシステムとは呼ばない.
Microsoft SQL ServerはNTサービスとして稼動
Microsoft SQL Serverはバックエンドに常駐しながら,クライアントアプリケーションに機能を提供するWindows NTサービスプログラムである.SQLエンタープライズマネージャは,Microsoft SQL Serverを操作管理するが,Microsoft SQL Serverそのものではない.あくまで,Microsoft SQL Serverのサービスをうけるクライアントである.これはMicrosoft AccessとJetデータベースエンジンの関係にも似ている.Microsoft Accessはユーザーが操作したりプログラミングをする環境であり,あくまでJetデータベースエンジンのサービスを受けているにすぎない.COMクライアントであるMicrosoft Accessは,DAO経由でCOMサーバーであるJetデータベースエンジンとして操作するのである.
負荷分散を決定する複数のフェーズ
負荷分散という話になると,サーバーデータベースとファイル共有型データベースの比較はさらに複雑になる.シンプルなクライアント/サーバーシステムの負荷分散は,リクエストの発行者と,それに応答する者という2者に分けることができる.SQLによる問い合わせを発行する者と,検索を実行して結果をリクエスターに返すというのが,データベースサーバーのスタイルである.それに対し,ファイル共有型データベースの場合,ディスクに収められているデータを問い合わせる者と,そのディスクにアクセスして読み取った結果を返答する者とで負荷を分散する.これではリクエスタの処理が多すぎて,負荷の分散が効率的になされているとはいえない.
しかし,この構造がネットワーク上に配置されると,少し意味が変わってくる.マルチユーザーが1台のファイルサーバーにアクセスする場面では,比較的ヘビーな検索処理などの負担が,各クライアントに分散されるのである.逆にデータベースサーバーのケースでは,負荷がサーバーに集中することになる.だからといってファイル共有型が,ネットワークを使ったマルチユーザー環境で有利だということにはならない.ネットワークトラフィックの増大という別要因が発生するからである.ネットワークのオーバーヘッドが,クライアント/サーバーシステム全体のパフォーマンスが低下する要因になっている現況では,これは大きなマイナス要因になる.
用途の差と機能の差
このように,Microsoft SQL Serverのようなデータベースサーバーと,Microsoft Accessのようなファイル共有型のデータベースでは構造上の違いがあることで,用途が決定づけられてくるのである.ただ,それ以上に,実際の両者の間にデータベースとしての機能の差がある.Microsoft Accessもデータベースとして必要十分な機能は搭載しているので,その差は意外と見えてこない.また,Microsoft Accessはデータベースフロンドシステムでもあるので,逆にMicrosoft Accessの方が高機能に見える場合もある.元々,Microsoft AccessとMicrosoft SQL Serverではアプリケーションとしての適用の範囲が違う.Microsoft SQL Serverと直接比較できるのは,Microsoft Accessに内蔵されているJetデータベースエンジンなのである.
Visual BasicはMicrosoft SQL Serverのネイティブ開発言語
Microsoft AccessとMicrosoft SQL Serverを比較する際に,それらがサポートするカテゴリーの範囲を揃えるためには,Microsoft SQL ServerにはVisual Basicを追加する必要がある.Visual Basic 5.0には,Visual Databaseツールというデータベース管理のためのツールが追加されたこともあり,Visual Basic 5.0とMicrosoft SQL Serverの組み合わせで,Microsoft Accessと同様に,データベースの管理,インタラクティブなデータの編集,プログラミングといったデータベースの操作が可能になる.そして,SQL-DMOと呼ばれる,Microsoft SQL Server自体をActiveXコンポーネントとして提供する機能により,Visual BasicとMicrosoft SQL Serverの強調関係はさらに強まる.既存のデータベースサーバーと開発ツールの組み合わせでは不可能であったようなデータベースエンジン制御が可能になる.Microsoft Accessアプリケーションのネイティブな開発言語がVBAであるように,Microsoft SQL Serverのネイティブの開発ツールはVisual Basicなのである.
AccessをSQL Serverにアップサイジングするためには,まずスキルのアップサイズを…
今回はMicrosoft AccessとMicrosoft SQL Serverを比較して,データベースとしての機能の差を解説する.Microsoft SQL Serverのスコープを逸脱するような比較に対してはVisual Basicを適用しよう.Microsoft AccessからMicrosoft SQL Serverへとアップサイジングをはかろうとしている方や,あるいはスキルのアップサイジングを考えている方の参考になるだろう.
まず,Microsoft SQL ServerとMicrosoft Accessの間にある設計思想の根本的な違いを理解しておく必要がある.Microsoft SQL Serverが高可用性・高信頼性に重点が置かれているのに対して,Jetデータベースエンジンは,貧弱な環境でも動作するように小型軽量に設計されている.もっとも,現在のようにメモリが低価格になった状況では,小型化のメリットは決定的な差にはならない.メモリさえ積めばA5サブノート機でもMicrosoft SQL Serverは快適に動作するのである.いずれは,Windows CEのようなハンドヘルドPCでもデータベースサーバーが動作するようになるだろう.
また,Microsoft SQL Serverが技術を習得したエンジニアを対象とした製品であるのに対して,Microsoft Accessは誰でも気楽に使えるように設計されている違いも大きい.スキルの不十分なユーザーが,この2製品を使用した場合,皮肉なことにJetデータベースエンジンの方が可用性は高くなる.少なくとも,不可解なエラーに悩まされる可能性は低い.ただ,この点に関してはMicrosoft SQL Serverの次期バージョンでは,メンテナンス性が大幅に改善される.これには非常に期待したい.メンテナンスコストの削減こそが,業務システムの最大テーマであるといってもいい今日の状況では,この長所は他のデータベース製品に対して大きなアドバンテージになる.
| 開発者の立場で言えば |
|---|
ストアドプロシージャ
開発者から見た場合の機能的な差としては,やはり,ストアドプロシージャを筆頭にあげることができる.ストアドプロシージャは,サーバー側に保存されるデータベースサーバー固有のプログラムである.この機能は,サーバーがファイルサービスしか提供しないJetデータベースエンジンでは,理論的に装備しえない.とはいっても,Jetデータベースには「クエリー」という名称のストアドクエリー機能がある.しかし, Microsoft Accessの「クエリー」は単一のSQL文の実行しかできないし,当然,ループや条件分岐のような制御構造をもたない.それにサーバー側に存在しているわけではないので,ネットワークトラフィックや問い合わせの回数を減少するというメリットもない.どちらかといえば,インタラクティブに操作した場合の操作性を追求したものであるといえる.そのような用途においては,サブクエリーを作成する場合にクエリーをネストして使用できることなどのメリットも多い.
複数のSQLを同時に実行することで,通信の負荷を軽減
Microsoft SQL Serverの場合はTransact-SQLと呼ばれる拡張SQLによって記述される.ストアドプロシージャを使うと,複数のSQLステートメントを同時に実行できるので,特定の処理を行なう場合,クライアントの通信回数を削減することができる.
たとえば,\10,000以上の製品を購入した顧客に対して,10%のディスカウントを実施するようなビジネスロジックを実現したいとする.ストアドプロシージャを使用しない場合には,次のような2つのプロセスが必要になる.
(1)\10,000以上の金額を購入した人のリストを要求する.
(2)それらのユーザーに対して,10%のディスカウントを実施する.
このようにサーバーに対して,2回の要求を行なう必要がある.これら2つの処理をストアドプロシージャに記述しておけば,クライアントは一回ストアドプロシージャを呼び出すだけで,同様の処理を実行する.メリットは単にリクエストの回数が減るだけではない.要求に対する結果をネットワーク経由で取得する必要もなくなるので,ネットワークトラフィックも減少する.また,ストアドプロシージャは,常にサーバー側に保持されるため,ディスカウントの割合を15%に変更するような場合でも,サーバー側のストアドプロシージャだけ変更すればいい.3階層アーキテクチャとして構成されているので,クライアントのアプリケーションを再インストールする必要がない.これは,そのまま,TCOの削減につながる.
Transact-SQLで記述
ストアドプロシージャを作成するには,Transact-SQLのCREATE PROCステートメントを利用する.ステートメントはISQLやSQLクエリーツールで実行してもいいし,あるいはエンタープライズマネージャの「ストアドプロシージャ」フォルダを右クリックして,メニューから[新規ストアドプロシージャ]を選択してもいい(図1).
図1:ストアドプロシージャの作成
次のサンプルでは,まず初めに該当の顧客が当日に注文したレコードの総数を問い合わせる.もし,当日の注文がまだなかったら,メッセージを返してプロシージャを中断する.注文がある場合は,注文内容を取得するためのクエリーを改めて実行する.
CREATE PROC sql_slip @code_client int AS Declare @count_order int SELECT @count_order = count(*) FROM SQL_Order where Code_client = @code_client and convert(varchar(8),Date_order,11) = ⇒ convert(varchar(8),getdate(),11) if @count_order = 0 begin SELECT err_message = '本日の注文はまだありません.' return end Declare @total_order int SELECT @total_order = convert(decimal(10,0), ⇒ sum(SQL_Article.Price * Number)) FROM SQL_Order,SQL_Article where SQL_Order.Code_article = SQL_Article.Code_article GO注文の有無の判断をクライアントではなく,サーバー側が行なっているため,クライアントからの問い合わせが一回ですんでいる.このプロシージャをVisual Basicから実行するためには,RDOのrdoConnectionオブジェクトのExecuteメソッドの引数にプロシージャ名を渡せばいい.直接呼び出すならば,ISQLやSQLエンタープライズマネージャのSQLクエリーツールでプロシージャ名を指定する.
実行時のコンパイル時間を節約
また,ストアドプロシージャのメリットのひとつに,SQL文を事前にコンバイルできるというメリットもある.SQLを普通に実行するときのように実行時に構文の解釈やコスト評価をするのではなく,ストアドプロシージャの作成時にこれらの解析を実行しておくのである.短時間で終了するような問い合わせの場合や,複雑な構文をもつSQL文の場合,相対的にこれらの解析に消費される時間の割合は少なくない.問い合わせの種類によっては,半分以上のコストを費やすこともある.
OLEオートメーションストアドプロシージャによる機能の拡張
ただ,ストアドプロシージャを記述するためのTransact-SQLのプログラミング能力は,Visual Basicのような汎用言語に比べてかなり貧弱なため,記述できるロジックには限界がある.それを補うために用意されたのが,OLEオートメーションストアドプロシージャである.ストアドプロシージャをVisual Basicで記述できるという意味において,この拡張機能はVisual Basicプログラマにとって,相当な可能性をもつ.Visual Basicや他の言語で開発されたCOMコンポーネントを,Microsoft SQL Serverのストアドプロシージャから利用する機能である.この機能を装備したMicrosoft SQL Server ver. 6.5が発表された時点では,Visual Basicはインプロセスで動作するマルチスレッドに対応したCOMコンポーネント(当時はOLEオートメーションサーバーと呼ばれていた)を作成できなかった.そのため,この機能はVisual Basicデベロッパにとってあまり現実的とはいえなかったし,Visual C++によるCOMコンポーネント開発も,今ほど環境は整備されていなかった.
アパートメントモデルの採用でVisual Basicのコンポーネントもマルチスレッドに対応
しかし,現在のVisual Basicは,アパ―トメントモデルのマルチスレッド対応コンポーネントを作成できる.インプロセスのCOMコンポーネントの呼び出しは高速である.ただし,これらのCOMコンポーネントは,Microsoft SQL Serverが稼動しているプロセスと同じプロセスで動作するため,問題のあるプログラムを作成すると,データベースサーバーごとダウンすることになるので注意が必要だ.また,コンポーネントのライフサイクルがプロシージャ単位なので,複数のストアドプロシージャをまたいでインスタンスを共有することができない.インプロセスサーバーの呼び出しが高速だとはいっても,インスタンスの作成には,それなりのコストが消費される.とはいっても,2回目以降はディスクキャッシュの効果もあるので,クエリーの実行,データの転送といったデータベース問い合わせ処理全体にかかる時間からみれば,問題にはならないだろう.
この拡張機能は優れたアイデアなのだが,Microsoftは,この機能を前面に押し出そうとはしていない.もっとも,Microsoftが力を入れようが入れまいが,新しい技術を導入する場合には独自の調査が必要になるのだから,調査の結果がよいならば問題はない.
トリガはイベントドリブンのストアドプロシージャ
トリガもJetデータベースエンジンではサポートしない有用な機能のひとつである.しかし,トリガはストアドプロシージャとは違い,原理的にはファイル共有型のデータベースでも実装が可能なはずである.しかし,Jetデータベースエンジンを含めて,メジャーな製品にはこの機能を備えている製品はない.
トリガとは,データの挿入や更新などの特定のアクションに対して,自動的にストアドプロシージャやSQL文を実行する機能である.たとえば,納品テーブルにデータが挿入されたときに自動的に在庫テーブルの値を追加したいような処理があったとする.この処理は当然,クライアントから実行することも可能である.納品テーブルに対してInsert文を実行した後で,納品テーブルにUpdate文を発行すればいい.しかし,これではネットワークを介した通信の回数が増加するし,納品テーブルを操作するすべてのアプリケーションに同様のロジックを実装しなければならない.結果としてシステムの堅牢性と保守性が犠牲になる.
トリガを指定した場合,サーバー側にロジックを記述しておくだけで,納品テーブルを操作するあらゆるクライアントからの操作に対応できる.また,ロジックの変更に対して,サーバーの変更だけで対応できるのは,ストアドプロシージャと同様である.というのは,トリガはストアドプロシージャの一種だと定義できるからだ.Visual Basicのプロシージャに対してイベントプロシージャがあるように,データベースサーバーはトリガをサポートする.つまり,イベントドリブンなストアドプロシージャがトリガの実体である.
SQLエンタープライズマネージャでトリガを作成
トリガを作成するには,SQLエンタープライズマネージャでテーブルを指定してから右クリックメニューで[トリガ]を選択する(図2).[トリガの管理]ウィンドウでCREATE TRIGGERステートメントに続けてトリガの名前を指定する.FORの後に反応するアクションを記述し,AS以降が実行するステートメントである.
次のトリガはテーブルのデータが変更されたときに EFFECTIVE_DATE項目に当日の日付を自動的に設定するためのものである.このトリガはデータの更新時と挿入時に実行されるため,クライアントアプリケーションの処理に関係なく, EFFECTIVE_DATE項目には最新の日付が入力される.
CREATE TRIGGER ACCOUNT_DATE ON dbo.ACCOUNT FOR INSERT,UPDATE AS update ACCOUNT SET ACCOUNT.EFFECTIVE_DATE = getdate() FROM inserted WHERE ACCOUNT.ACCNT_CD = inserted.ACCNT_CD図2:トリガの作成
| 信頼性を求めて |
|---|
ログベースのトランザクション管理により高い対障害性を実現
Microsoft SQL ServerのJetデータベースサーバーのアドバンテージとして,ログベースのトランザクション管理機能がある.Jetデータベースエンジンもトランザクションの制御は可能だが,ログをベースにしていないため,管理の範囲には限界がある.
このログに対するポリシーの違いは,サーバーデータベースとファイル共有データベースの本質的なコンセプトの違いだといえる.データベースサーバーに要求される最も重要なミッション,それはパフォーマンスでも高機能でもなく信頼性である.Microsoft SQL Serverのように高信頼性を目標に設計されたデータベースサーバーは,Insert,Update,Deleteといった更新処理を行なう直前に,これから自分が実行する処理をログファイルに記録として残す.これにより,データベースサーバーはシステムがクラッシュする直前までのデータの復元を保証する.データを収納したディスクがクラッシュする場面を想像してほしい.もし,ログがなかったとしたら,データが保証されるのは,直前のバックアップの瞬間までである.最終バックアップ以降に登録したデータは闇に消え去ることになる.
バックアップとログ
しかし,ログが残されていれば,最後のバックアップを元にして,ログに記されている操作を復元することで,クラッシュ直前の状態を再現することができる.だから,Microsoft SQL Serverのバックアップデータには,どの時点までの処理が記録されているかのタイムスタンプが刻印されている.でなければ,ログを元に再現するための手がかりが失われるからである.
もちろん,再現できるのはログが障害が起こったのとは物理的に別のディスクに保持されている場合だけである.ログも同時に破損した場合は,最後にログをダンプした時点までが復旧の対象になる.
ログに残されたデータはトランザクションロールバックにも用いられる.ある実行単位が完全に終了していない場面では,ログをベースに処理をさかのぼるのである.それにログのデータは複数のデータベースをレプリケーションする場合にも用いられる.Jetデータベースエンジンもデータのレプリケーション機能をサポートしているが,レプリケーションマネージャを用いて複製の指定をした時点でテーブルを改変する.また,レプリケーションのメカニズムも十分に信頼性の高いものではない.
もっとも,レプリケーションを行なうには,データの競合が起こらないように精密にテーブル設計をする必要がある.この前提がない限り,レプリケーションを使用した実用的なシステムは成立しない.また,ネットワークの安定性,レプリケーションのタイミングなど,クリアしなければならない条件は多い.メーカーも一時は,レプリケーション機能の搭載をセールストークにしている時期もあったが,最近ではすべてのデータベースサーバーに搭載されてしまったために,あまり,前面には出さなくなった.同時に複数の更新が発生するレプリケーションデータベースは,整合性の保持というデータベースの最優先の命題と矛盾するからだろう.
図3:バックアップのスケジュールを指定
|
バックアップツール
ログとバックアップデータの緊密な関係にともない,バックアップを管理する機能が充実していることもMicrosoft SQL ServerのMicrosoft Accessに対するアドバンテージだといえる.Jetデータベースエンジンはファイルそのものがデータなので,普通のファイルのバックアップと同様の手段で予備データの作成ができる.それに対して,Microsoft SQL Serverのデータは専用のバックアップアプリケーションによるバックアップをする必要がある.バックアップツールはSQLエンタープライズマネージャに統合されており,バックアップを作成する時刻や時間の間隔を指定できる(図3).また,タスクのスケジューリングを使用して,バックアップ以外の操作をスケジュール化することも可能である.
| その他の機能 |
|---|
デバイスのミラーリング機能
フォールトレラント性を向上させる機能の一環として,データを格納するためのデバイスを,ミラーリングする機能もMicrosoft SQL Serverは提供する.しかし,これらの機能は,データベースサーバーのOSへの移植性を確保するために用意されている機能だといってよい.つまり,ディスクミラーリングをサポートしていないOSに同製品を移植する際に,自前のミラーリング機能を用意しておいた方が有利だという戦略である.しかし,Microsoft SQL Serverのように,Windows NT専用で作られているデータベースサーバーにとっては,このような実装法のもたらすメリットは少ない.
データベースとメールとの連携
Microsoft SQL Serverがもつ興味深い機能のひとつに,SQL Mailがある.これはMicrosoft SQL Serverをひとつのメールアカウントとして設定してメールの送受信ができるようにする機能である.Microsoft SQL Serverがメールクライアントとして動作するのである.たとえば,トリガと併用して,特定のテーブルにデータの追加が発生した場合に,内容をメール送信するようなことも可能だし,また,逆にメール経由で問い合わせを実行して結果を受信することもできる.電子メールによるコミュニケーションが一般的になりつつある今日においては,有効な用途を見つければ利用する価値があるだろう.
ユーザー権限の設定
Microsoft Accessもログインするユーザーを管理することができるが,Microsoft SQL Serverではより細かい設定が可能である.各ユーザーごとにアクセスする権限を細かく設定することができる.指定によっては,列単位でのアクセス権設定も可能である(図4).また,グループを作成して複数のユーザーに同時に権限を設定できる.さらに,ユーザーID等の設定をストアドプロシージャによって行なううことができるため,リモート環境からアクセス権などの指定も行なえる.
図4:アクセス権の設定
WebアシスタントによるWebパブリッシング
Microsoft SQL Serverはアプリケーションの開発環境を備えてない.唯一の例外がSQL Server Webアシスタントである.この機能はウィザード形式で設定することで,データベースの任意のデータをHTMLファイル化する(図5・6).スケジュール化することもできるし,トリガをベースに新しいHTMLファイルを作成することもできる.しかし,生成されるHTMLファイルはあくまでもスタティックなものであり,ユーザーのリクエストに対して動的に作成されるものではない.Microsoft AccessがASPファイルの生成機能をもっているのに比べると見劣りがする.Microsoft SQL Serverでアブリケーションを開発するにはVisual InterDevやVisual Basicを使用することが必須となる.
図5:ウィザードでHTML化するデータを指定
|
機能の差よりも可用性の差
総じていえば,Microsoft SQL ServerとMicrosoft Accessの違いを決定づける差は,機能の差というよりは,データボリュームに対応する可用性や,耐障害性の高さだということができる.特にEnterprise Editionの存在によるハイエンドサポートには注目すべきだろう.また,専任の管理者が必要か否かという差でもある.結局は人件費がもっともコストを消費する部分であるから,その削減効果を狙ったMicrosoft SQL Server ver. 7.0に対する期待は大きい.