「データベース」と聞いてどのように思うでしょうか。「何か難しそうで自分には関係ないもの」と感じられる人もいるかもしれません。確かに,企業システムで使っている顧客管理データベースや売上管理データベースは大規模で複雑なものが多く,職業プログラマ以外の方にはとても手におえそうにありません。

 でも,データベースが活躍するのは,企業システムだけではありません。例えば,同窓会名簿など個人で使うちょっとしたアプリケーションも,データベースを使うことでずいぶん楽に作れるようになるのです。

 あるいは,「データベースだったら,年賀状作成ソフトについている住所管理データベースをずいぶん前から使っているよ」という方もいるかもしれません。そうした方はきっとデータベースの便利さを実感していますから,改めてご利益を説明する必要はないでしょう。この特集を読んで,データベースの中身や仕組みについての理解を深めてください。データベースを使った新しいアプリケーションのアイデアが湧くかもしれません。

ある決まりごとに従って格納したデータの集まり

 最初に,データベースとは何か,ということについて説明しておきましょう。ある人は,「読んだ本の感想をテキスト・ファイルにどんどん書き込んで,“読書データベース”を作っているんだ」と言うかもしれません。しかしこうしたファイルはここでは,データベースと呼びません。

 データベースは,ある規則にしたがってまとめられたデータの集まりを指します。例えば,現在の主流であり,この特集で取り上げるリレーショナル・データベース(RDB:Relational DataBase)は,すべてのデータをテーブルの形式でまとめたものです。テーブルについては,後で詳しく説明しますが,とりあえずここでは,2次元の表のようなものと考えておいてください。

 データベースは入れ物に過ぎません。データベースにデータを格納したり,格納してあるデータを検索するなどの管理を行うには専用のソフトウエアを使います。こうしたソフトウエアをデータベース管理システムと呼びます。

 RDBの例で説明しましょう。RDBには,複数のテーブルが含まれていて,テーブルのマス目にはそれぞれデータが格納されています。利用者や開発者は,リレーショナル・データベース管理システム(RDBMS:Relational DataBase Management System)を介して,RDBにアクセスし,データベース内のデータを検索したり,テーブルを作成したりします。

 データベース技術は奥が深いですから,すべてを理解しようとすると大変です。しかし,何ごとにも,ここさえ押さえておけば,とりあえずは大丈夫,という基本があります。RDBの場合それが,先ほど説明した「テーブル」,そして「正規化」「SQL」です。

 RDBでは,必ずテーブル形式でデータを格納しなくてはなりません。テーブルについて理解することは,RDBを理解するうえで不可欠なのです。さらに,データを素早く検索したり,格納したデータを効率よく保守するには,テーブルをうまく作る必要があります。その際に指針になる決まりごとが,正規化です。

 SQLは,RDBにデータを格納したり,検索したりする際に使う命令です。RDBでは基本的にすべての操作は,RDBMSにSQLを渡すことにより行います。SQLについて学習すれば,RDBのデータを自由自在に扱えるようになるのです。ここでは,これら3本柱について順番に,基礎知識と,それぞれの関連情報について説明していきます。

テーブルはすべての基礎

 リレーショナル・データベース(RDB)では,データはテーブルと呼ばれる2次元の表に格納されます。テーブルは「行(row)」と「列(column)」で構成し,それぞれの列には名前(「列名」)が付いています。

 図1はある会社の社員の情報をテーブルにまとめたものです。それぞれの列には,どのような種類のデータを格納するのかを表す列名がついていて,各行に社員一人ずつの情報を格納します。そして,社員が増えるたびに新しい行として追加していくわけです。

図1●RDBのテーブルの構造
図1●RDBのテーブルの構造

 テーブルでは,行と列を指定することにより,データを特定できます。例えば飯田高志さんの部署を知りたい場合,図1のテーブルの氏名の列で飯田高志さんを探し,飯田さんの行の部署名の列を見ると所属部署がわかるわけです。

 ここまで読んで,Excelなどのスプレッドシート・ソフトを使ったことがある人は疑問を抱くかもしれません。Excelでも,図1と同じような2次元の表を作れます。RDBのテーブルとExcelで作る2次元の表では何が違うのでしょうか。

 RDBのテーブルでは,データの検索を効率よく実行したり,データベース内容の不整合が発生しにくいように,スプレッドシート・ソフトとは異なる仕組みがいろいろ取り入れられています。ポイントは次の4点です。

ポイント1:各列は一意の名前を持つ

 RDBのテーブルでは,各列につける名前である列名が,ほかの列と重複してはならないという決まりがあります。実際,RDBソフトを使ってテーブルを作成するときに,列名が重複するとエラーが発生します。これを,「各列には一意な列名を付ける」などと言います。

 RDBでは列に対して条件を指定して,該当するデータを検索することがよくあります。例えば図1のテーブルで,性別が男である社員を検索するような場合です。RDBでは列名で列を区別しますから,列名がダブっているとどの列を検索すればよいのかわからなくなってしまいます。

 これに対してExcelの表では,同じ名前の列があってもエラーになりません。例えば,住所という名前を二つの列に付けて,一方には県名を格納し,もう一方には市町村名と番地を格納する,といったこともできます。

ポイント2:主キーが存在する

 RDBのテーブルは,該当する行をただ一つに決めることができる列を持っていなければなりません。例えば,図1のテーブルであれば,社員番号の列の値を決めると,対応する社員がただ一人に決まります(氏名では同姓同名がいますね)。該当する行をただ一つに決めることができる列を「主キー」,あるいは「識別キー」と呼びます。

 主キーは行をただ一つに決めるためのものですから,同一の値を持つ行が複数あってはいけません。加えて,すべての行は主キーに値を持っていなければなりません。すなわち,主キー(先の例で言うと社員番号)の値が入っていない行があってはいけません。ちなみに,値が入っていない状態のことを「NULL(ヌル)」と呼びます。

 複数の列を組み合わせて主キーとして扱うことも可能です。図1で言えば,もしこの企業に「一つの部署には同姓同名の社員を配属しない」という規則があって,それを将来にわたって厳守するとすれば,氏名と部署名を組み合わせて主キーとして扱うこともできます。例えば,「第1営業部の吉田正美さん」と言えば,対応する社員がただ一人に決まるわけです。組み合わせて主キーとして扱える列のことを,「連結キー」あるいは「複合キー」と呼びます。

ポイント3:テーブル間を関連付けられる

 図1のテーブルでは,部署名が変更になった際に,該当するデータをすべて修正しなくてはなりません。例えば,第1営業部が海外営業部に名称を変更した場合,吉田正美さん(男)と福山友子さんの部署名をそれぞれ,海外営業部に直す必要があります。

 修正するのが数カ所程度ならいいですが,数百人規模の部署だったら大変な作業です。多くの行を持つテーブルにおいて,修正する個所は少なければ少ないほど良いと言えます。手間が省けるだけでなく,更新漏れによる不整合を防ぐことにもなるからです。

 そこで,データはできるだけ重複して持たせない,あるいは同じデータはできるだけ1カ所で管理するようにしたい,という要求が生まれます。RDBでは,複数のテーブルを作成し,それらの間に「関連(リレーションシップ)」を持たせることによって,こうした要求に応えられるようになっています。

 図2をご覧ください。各部署に対して部署コードを割り当てて,部署名を主キーとするテーブル(部署テーブル)を別に作成しました。さらに,図1のテーブルにおける部署名の列を部署コードに置き換えます(社員テーブル)。

図2●図1のテーブルを分割したところ。二つのテーブルには,部署コードを通じてリレーションシップ(関連)が付けられている
図2●図1のテーブルを分割したところ。二つのテーブルには,部署コードを通じてリレーションシップ(関連)が付けられている

 こうしておけば,社員番号を指定したとき,両テーブルに共通して存在する列である部署コードを介して,部署テーブルから部署名を取得できます。部署名に変更があったときには,部署テーブルの対応する部署名を修正するだけで済みます。

 図2の部署テーブルにおいては,部署コードが主キーになります。一方,社員テーブルにおける部署コードは,ほかのテーブルの主キーになっていることから「外部キー」と呼びます。

ポイント4:制約を設定できる

 RDBではテーブルや列,また列と列の関連に「制約」を持たせることができます。制約とは,RDBの内容を整合性が取れた状態に保つことを目的として,テーブルに格納するデータに課す条件のことです。制約を設定することで,意図しないデータや間違ったデータの入力を防げるので,データベースを管理する際の手間を軽減できます。

 例えば,図2の主キーである社員番号の列に対しては,ポイント2で説明したように,「値が重複してはならない」「NULLであってはならない」といった制約があります。これらをそれぞれ,「一意制約」「NOT NULL制約」といいます。主キーに対するこうした制約はまとめて,「主キー制約」と呼ばれます。

 ほかに,氏名の列に対しては,値がNULLでは困るのでNOT NULL制約をつけておきます。また性別は男か女かのいずれかですから,それ以外の値の格納を許さない「CHECK制約」を付けるのが良いでしょう。

 外部キーである部署コードに対しては,「参照整合性制約」と呼ぶ制約を付けます。参照整合性制約とは,関連付けられているテーブルで主キーの値として登録されていない値は,その列に格納できないということです。

 図2の社員テーブルに新しいデータを追加する場合を考えてみましょう。もし何かのミスで存在しない部署コードを入力しようとした場合,参照整合性制約が設定されていなければそのまま格納されてしまいます。追加する社員は,部署テーブルに存在するいずれかの部署に所属するはずですから,これは明らかにおかしいことになります。

 外部キーである部署コードに参照整合性制約を設定しておけば,部署テーブルに存在しない部署コードを社員テーブルに追加できません。同時に,社員テーブルから関連付けされている部署テーブルの行を削除することもできなくなります。不整合を引き起こすような更新をあらかじめ防ぐことができるわけです。

知っておきたいキーワード
XMLデータベース

 リレーショナル・データベース(RDB)ではテーブル形式で表現したデータをデータベースに格納しました。データを表現する形式はテーブルに限りません。ここでは,XML(Extensible Markup Language)形式のデータを格納するXMLデータベースについて紹介します。XMLデータベース自体は以前からあるのですが,最近になってXMLを利用するアプリケーションが増えてきたため,改めて注目されています。

 リストAは書籍のタイトル(title),著者(author),価格(price),発行年月日(date),記事(article)を記述したXML文書の例です。タグの入れ子構造によって,データの階層構造が表現されていることがわかります。

<?xml version="1.0"?>
<books>
<book>
<title>日経ソフトウエア11月号</title>
<author>日経BP社</author>
<price>980</price>
<date>2004/09/24</date>
<articles>
<article>データベース</article>
<article>Java</article>
</articles>
</book>
<book>
<title>日経コンピュータ9月6日号</title>
<author>日経BP社</author>
<price>980</price>
<date>2004/09/06</date>
<articles>
<article>社員監視時代</article>
<article>ザ・プロジェクト</article>
</articles>
</book>
</books>
リストA●XML文書の例

XMLデータをツリー構造で格納

 XML文書をデータベースに格納するには2種類の方法があります。一つは,XML文書をそのまま扱えるネイティブXMLデータベース(以下,単にXMLデータベースと呼びます)を使うこと。もう一つは,XML形式のデータをテーブル形式に変換して格納するXML対応RDBを使うことです。

 図A(a)はXMLデータベースのデータ格納構造のイメージです。リストAのXML文書をツリー構造で格納します。

図A●リストAのXMLデータの格納構造。(a)XMLデータベース,(b)XML文書の要素や属性をレコードに対応付けて格納するRDB。ほかに,XML文書をテキストでRDBにそのまま格納したり,ツリーに展開してRDBに格納するタイプがある
図A●リストAのXMLデータの格納構造。(a)XMLデータベース,(b)XML文書の要素や属性をレコードに対応付けて格納するRDB。ほかに,XML文書をテキストでRDBにそのまま格納したり,ツリーに展開してRDBに格納するタイプがある  [画像のクリックで拡大表示]

 多くのXMLデータベースが備える特徴の一つは,スキーマ(データベース構造の仕様)の定義を必要としないことです。XML文書には,構造とデータの両方を記述しますから,スキーマなしでデータの種類を判別できるからです。データの構造を変更したり,項目を追加するときにいちいちスキーマを修正する必要がありません。

 RDBと比べたときの注意点として,XMLデータベースは更新処理を不得手としていることが挙げられます。更新の単位,ロックの範囲,トランザクション機能は製品によって様々であるため,導入の際には十分な検討が必要です。

RDBにXML形式のデータを格納する

 XML対応RDBの格納方法には大きく三つあります。一つは,XML文書をテキストとしてそのまま格納するタイプです。実装は簡単ですが,XMLデータベースが持つ柔軟性は持っていません。検索する場合も,XMLデータを取り出して解析する処理が必要になるため,パフォーマンスが悪くなりがちです。内部にインデックスを持たせることによってパフォーマンスを改善しているものあります。

 ニつ目はXML文書の要素や属性を,RDBのレコードに対応付ける(マッピングする)タイプです(図A(b))。テーブル形式で格納しますから,格納後はSQL文で操作できます。このタイプの問題点は,XML文書の構造やRDBの構造によってはマッピングが困難な場合があること,マッピング処理の負荷がかかることです。

 三つ目は(図A(a))と同じように,XML文書をDOM(Document Object Model)ツリーと呼ばれるオブジェクトに展開してRDBに格納するタイプです。データ構造を解析した状態で保存しているため,高パフォーマンスが期待できます。XMLデータベースとRDBのメリットを併せ持つタイプと言えます。