1-1データベースの種類
土曜の朝9時、こむぎ堂のレジの前に、食パンの予約票を持ったお客さまが2人並びました。店長が予約台帳を開くと、同じ時刻の欄に「佐藤さま 食パン2斤」と「さとう様 食パン2本」が、違う字で書かれています。どちらも同じ人の予約のようで、電話で確かめようにも、片方の番号は引っ越す前の古いものでした。棚に残っている食パンは1斤だけです。お客さまに頭を下げたあと、店長はため息まじりに言いました。「台帳を表計算ソフトに写しておけば、こんなことにはならなかったのかな」。ミナトは相棒に聞いてみます。「台帳をそのまま表に写したら、取り違えは止まるかな」。相棒の答えは「写すだけなら、同じ矛盾がそのまま表に移るよ」でした。
台帳の困りごとは、紙であることそのものより、同じことが何か所にも書かれていることから来ていました。名前の書き方がそろっていません。電話番号は予約のたびに書き写され、古い番号が残ります。在庫の数と予約の数を、一つの場所で照らし合わせる人もいません。どれも、表計算ソフトに写しただけでは直りません。
決まった形で整理して蓄え、何人もが共有して使えるようにしたデータの集まりを、データベースといいます。データベースを作るときは、データをどんな形で持つか、誰がどう管理するか、矛盾が出ないように表をどう分けるかを決めていきます。最初の「どんな形で持つか」には、いくつもの答えがあります。いま最も広く使われているのは、データを行と列の表で表し、表どうしを共通の項目で結び付ける方式です。
ここから基本情報!データベースの種類の名前
表で持つ方式をRDB(Relational Database:関係データベース)といいます。予約の表とお客さまの表を別々に作り、両方に「お客さま番号」の列を置けば、その値をたどって2つの表を結び付けられます。表どうしのつながりは、データの中の値で表されます。
RDBが広まる前には、データどうしのつながりを、決まった道筋として持つ方式が使われていました。HDB(Hierarchical Database:階層型データベース)は、データを親子の木の形で持ちます。「店」の下に「日付」、その下に「予約」とつなげると、1つの親は子をいくつも持てますが、子が持てる親は1つだけです。日付ごとに予約をたどるのは得意でも、お客さまごとに予約をたどりたくなると、別の木を作って同じ予約を二重に持つことになります。
NDB(Network Database:網型データベース)は、この制限をゆるめて、子が親を複数持てるようにした方式です。1件の予約を「日付」と「お客さま」の両方の子にできるので、データを二重に持たずに済みます。そのかわり、データをどの道筋でたどるかを、プログラムの側が知っていなければなりません。
HDBやNDBのように、レコードどうしのつながりの構造をあらかじめ決め、その構造に沿ってデータを格納する方式を、まとめて構造型データベースと呼びます。値で表どうしを結び付けるRDBは、ここには入りません。基本情報のシラバスでは、RDB・HDB・NDBと並ぶ用語の一つとして挙げられています。
表にも木にも収まりにくいデータには、そのデータに合わせた方式があります。OODB(Object Oriented Database:オブジェクト指向データベース)は、データとそれを扱う操作をひとまとまりにしたオブジェクトを、プログラムの中の形のまま格納します。XMLデータベースは、XMLで書かれた文書を入れ子の木の形のまま持ち、XPathやXQueryといったXML向けの問合せ言語で検索します。
シラバスの用語例には無い語ですが、文書と文書をリンクで結び、リンクをたどりながら情報を探せるようにしたものをハイパーテキストデータベースと呼びます。文字や数値だけでなく、画像・音声・動画などをまとめて管理するものはマルチメディアデータベースです。通販の商品写真や、焼き方を撮った動画まで一緒に管理したいなら、この種類が候補になります。
基本情報の範囲ここまで
こむぎ堂の予約台帳は、お客さま・予約・商品がそれぞれ何件もあり、互いに結び付いています。表で持つ方式が最初の候補になるのは、このためです。ただ、相棒は表のほかにも、まだ見せたい持ち方があるようでした。
1-2NoSQLとインメモリデータベース
相棒は画面に、同じ予約を3通りの形で並べて見せました。1つめは行と列の表、2つめはお客さま1人ぶんを1枚の書類にまとめた形、3つめは常連さんどうしの「紹介した」「紹介された」を線で結んだ形です。ミナトは3つめの図を見て、「これは表にすると、かえって分かりにくくなりそう」とつぶやきました。
表で持つ方式は、項目が決まっていて、たくさんの表を組み合わせて正確に扱うデータに向いています。一方で、データの量が非常に多い場合や、1件ごとに項目がまちまちな場合、つながりそのものを調べたい場合には、表の形が足かせになることがあります。RDBのような決まった表の形を使わずにデータを扱うデータベースを、まとめてNoSQLと呼びます。名前は、RDBへの問合せに使う言語SQL(第2章で扱います)に由来し、「Not only SQL」の意味だと説明されることが多い語です。
いちばん単純な形は、キーと値の組だけでデータを持つキーバリューストア(KVS、キーバリュー型データベース)です。キー「予約1024」に値「佐藤さま、食パン2斤、土曜9時」を結び付けておけば、キーを指定するだけで値がすぐに取り出せます。仕組みが単純なぶん速く、データを何台ものサーバに分けて置くのも簡単です。そのかわり、「土曜の予約を全部」のように値の中身で探すのは得意ではありません。
相棒の2つめの形がドキュメント指向データベースです。JSONなどで書いた文書(ドキュメント)を1件の単位として格納します。お客さま1人ぶんの文書の中に、名前・電話番号・これまでの予約を入れ子にしてまとめられ、ある人には「アレルギーのメモ」、別の人には「配送先」と、1件ごとに項目が違っていてもかまいません。
3つめの形はグラフデータベース(グラフ指向データベース)です。データを点(ノード)と、点どうしを結ぶ線(エッジ)で表します。「Aさんが Bさんを紹介した」「BさんがCさんを紹介した」と線をたどれば、紹介の輪がどこまで広がったかがすぐに分かります。SNSの友だち関係や、商品のおすすめのように、つながりが主役のデータに向いています。
ここから基本情報!集計と速さで選ぶ持ち方
表の形を保ったまま、格納の仕方を変える方式もあります。ふつうのRDBは1行ぶんのデータをまとめて記憶装置に置きますが、列指向データベースは同じ列の値をまとめて置きます。1年分の予約から「数量」の合計を出すなら、数量の列だけを読めば済み、名前や電話番号の列を読み飛ばせます。大量のデータを集計・分析する用途に向いていて、1件ずつ書き込む処理は行単位の方式のほうが得意です。
速さを求めて、データを置く場所そのものを変えることもあります。データをハードディスクやSSDではなく主記憶(メモリ)の上に置いて処理するのがインメモリデータベースで、主記憶データベース(Main Memory Database)とも呼ばれ、MDBと略されます。英語の文献ではMMDBと略すことが多い語です。記憶装置への読み書きを待たずに済むので応答が速くなります。主記憶は電源が切れると中身が消えるので、更新の記録を別に書き残すなどの仕組みと組み合わせて使います。
基本情報の範囲ここまで
ミナトは、紹介のつながりはいずれグラフで見てみたいと思いながらも、予約台帳はまず表で作り直すことに決めました。お客さま・予約・商品という決まった項目があり、在庫の数と予約の数を正確に照らし合わせたいからです。
1-33層スキーマ
表を作る前に、店長から注文が出ました。「レジの画面にはお客さまの電話番号を出さないでほしい。でも配送を頼む人には住所が要るね」。ミナトは、見せる相手ごとに表を3つ作ろうとして、手を止めました。表を3つ作れば、電話番号を変えたときに3か所を直すことになり、冒頭の台帳と同じ形に戻ってしまいます。
使う人ごとに見せる項目を変えても、元のデータは1か所に置いておけます。データベースでは、利用者に見せる形と、データそのものの形、記憶装置への置き方を分けて考えます。分けておけば、レジの画面の項目を1つ増やしても、元の表の作りや保存のしかたには手を入れずに済みます。
ここから基本情報!データの見え方を3つの層に分ける
データの定義を3つの層に分けて考える方式を3層スキーマ(3層スキーマアーキテクチャ)といいます。スキーマは、データの構造を定義したもののことです。
いちばん利用者に近い層が外部スキーマ(副スキーマ)で、利用者やプログラムごとの見え方を定義します。レジの画面用の「電話番号を含まない予約一覧」や、配送係用の「住所つきの予約一覧」がこれにあたります。真ん中の概念スキーマは、こむぎ堂全体で共有するデータの論理的な構造で、どんな表があり、どの項目が入り、表どうしがどうつながるかを、見る人にも保存のしかたにもよらずに定めます。いちばん下の内部スキーマ(記憶スキーマ)は、データを記憶装置の上でどう並べ、どう探しやすくしておくかという、物理的な格納のしかたを定義します。
層を分けるねらいはデータ独立性を高めることにあります。データの格納のしかたや構造を変えても、それを使うプログラムを直さずに済む性質のことです。記憶装置を買い替えて並べ方を変えても、概念スキーマが変わらなければ画面のプログラムはそのまま動きます。これを物理的データ独立性といいます。全体の表に列を足しても、レジの画面の外部スキーマがその列を使っていなければ、レジのプログラムには影響しません。こちらは論理的データ独立性です。
基本情報の範囲ここまで
ミナトは、元の表は1つにして、レジ用と配送用には見せる項目を絞った画面を用意することにしました。電話番号を書き直す場所は、これで1か所だけになります。
1-4データモデル
ミナトはノートに「お客さま」「予約」「商品」と書き、3つを線で結びました。「1人のお客さまが何回も予約して、1回の予約で何種類もパンを頼む」。相棒が返します。「業務のつながりは描けたね。それを表で持つか、木で持つかは、また別の話だよ」
データの構造を、決まった約束に沿って表したものをデータモデルといいます。同じ「お客さま・予約・商品」のつながりでも、どのデータモデルで表すかによって、データベースの中の形が変わります。
ここから基本情報!設計の段階としてのデータモデル
データモデルは、設計の段階を表す言葉としても使われます。業務の言葉で描いたつながりの図(この章の概念設計の節で扱います)を、関係モデルなど特定の種類のデータベースの形に合わせて書き直したものが論理データモデルです。それを、実際に使うDBMSの仕様に合わせて、表の名前・列のデータ型・検索を速くする索引まで決めた形にしたものが物理データモデルです。業務の図から、データベースの種類に合わせた形へ、さらに製品に合わせた形へと、具体的になっていきます。
基本情報の範囲ここまで
こむぎ堂が選んだのは関係モデル(関係データモデル)です。データを行と列からなる表の集まりとして表し、表どうしは共通の列の値で結び付けます。もとになっているのは数学の集合の考え方で、表から行を選び出したり、2つの表をつないだりする操作も、集合の演算として定義されています。RDBは、この関係モデルに基づいて作られたデータベースです。
これより古い階層モデルは、データのつながりを親子の木の形で表します。1つの親が複数の子を持てますが、子が持てる親は1つだけです。会社の部署の組み立てのように、上下の関係がはっきりしたデータは素直に表せます。
ここから基本情報!網とグラフで表すデータモデル
子が複数の親を持てるようにしたのがネットワークモデル(網モデル)で、データのつながりを網目の形で表します。1件の予約を、お客さまとも日付とも結び付けられます。
つながりそのものを主役にするのがグラフ型のデータモデルで、データを点と線のグラフの形で表します。代表的な形が2つあります。プロパティグラフは、点にも線にも属性(プロパティ)を持たせる形です。「佐藤さま」の点に電話番号を、「紹介した」の線に紹介した日付を付けられます。トリプルストアは、「主語・述語・目的語」の3つの組(トリプル)でデータを表す形で、「佐藤さま・紹介した・鈴木さま」「鈴木さま・好きなパン・クロワッサン」のように1つの事実を1組で持ちます。Webの情報に意味を付けて記述するRDFという方式が、この形をとっています。
基本情報の範囲ここまで
もう一つ、データとそのデータを扱う操作をひとまとまりのオブジェクトとして表すのがオブジェクトモデルです。「予約」のオブジェクトが、予約の内容と一緒に「取り消す」「受け取り時刻を変える」といった操作を持つ、という表し方になります。プログラムをオブジェクトの組み合わせで書く考え方(オブジェクト指向)と相性のよいデータモデルです。
1-5関係モデル
ミナトが予約の表に列を並べていくと、相棒が一つ聞きました。「『数量』の列には、何が入ってもいいの?」。ミナトは台帳の端に書かれた「−3斤」という書き損じを思い出しました。受け取り時刻の欄には、閉店後の「19時」と書かれた行もありました。
表の列ごとに、入ってよい値の集まりを決めておけます。これを定義域(ドメイン)といいます。こむぎ堂の予約なら、「数量」の定義域は1から20までの整数、「受け取り時刻」の定義域は開店の7時から閉店の18時までの時刻、と決められます。定義域を決めておけば、「−3」や「19時」は表に入る前に断れます。
ここから基本情報!関係モデルの呼び方
関係モデルでは、表の各部分に決まった呼び名があります。表そのものは関係(リレーション)、表の1行はタプル(行、組)、表の1列が表す項目はアトリビュート(属性、列)です。関係は、同じアトリビュートの並びを持つタプルの集合として定義されます。集合なので、まったく同じタプルが2つ入ることはなく、タプルの並び順にも意味はありません。
あるタプルのあるアトリビュートに実際に入っている値を実現値といいます。「数量」の定義域が1から20までの整数なら、予約1024の行に入った「2」がその実現値です。実現値は、いつも定義域の中から選ばれます。
表の名前と、その表が持つアトリビュートの並びで表の構造を表したものが関係スキーマです。こむぎ堂の予約なら「予約(予約番号、日付、お客さま番号、受け取り時刻)」のように書きます。関係スキーマは表の型にあたり、中身のタプルが毎日増えたり減ったりしても変わりません。
基本情報の範囲ここまで
ミナトは、数量と受け取り時刻の決まりを相棒と一緒に書き出しました。表の形と、各列に入ってよい値が決まりました。残る心配は、この表を誰がどう守るのかです。
1-6データベース管理システム
土曜の朝、ミナトがレジで予約を入れていると、同じ時刻にネット予約からも注文が届きました。2つの画面が、同じ「食パン 残り1斤」の行を同時に書き換えようとしています。片方が書いた数字を、もう片方が上から書き消してしまったらどうなるのか。ミナトは、表を作っただけでは足りないことに気づきました。
データを決まった構造で蓄え、何人もが同時に使っても一貫性を保ち、必要なデータを効率よく取り出せるようにするソフトウェアを、データベース管理システム(DBMS:Database Management System)といいます。プログラムが記憶装置のファイルを直接読み書きするのではなく、DBMSに頼んでデータを出し入れします。そのおかげで、レジとネット予約の両方が、同じデータを同じ決まりで扱えます。
関係データベースを扱うDBMSはRDBMS(Relational Database Management System)と呼ばれます。表の作成から、データの検索・更新、利用者ごとの権限の管理までを受け持ちます。
DBMSの働きのうち、データを正しく安全な状態に保つものをデータベース制御機能といいます。何人もが同時に書き込むときの調整(同時実行制御、排他制御ともいいます)、停電や故障の後にデータを正しい状態に戻す障害回復、誰がどのデータを見たり変えたりしてよいかの管理が、ここに入ります。冒頭の土曜の朝に、残り1斤を2人に約束しないで済むのは、この同時実行制御のおかげです。くわしい仕組みは第3章で扱います。
ここから基本情報!DBMSの機能の分け方
DBMSの機能は、制御機能を含めて3つに分けて説明されます。表の名前や列、データ型といったデータの構造を定義するのがデータベース定義機能で、データ定義言語(DDL)を使います。データの検索・追加・更新・削除を行うのがデータベース操作機能で、データ操作言語(DML)を使います。この2つにデータベース制御機能を加えた3つが、DBMSの代表的な機能です。
基本情報のシラバスでは、DBMSの用語例として保全機能も挙がっています。障害回復や同時実行制御などによって、データを正しく一貫した状態に保つ働きを指す語と考えてよいでしょう。データベース制御機能と重なる部分が大きく、資料によって分け方が違うので、「データを正しい状態に保ち続ける働き」として覚えておけば足ります。
データの機密を守る働きはデータ機密保護機能と呼ばれます。利用者ごとにアクセスの権限を設定し、必要に応じてデータを暗号化して、許可のない人に中身が渡らないようにします。不正アクセスや漏えいからデータを守るための対策全体はデータセキュリティといい、データの機密性・完全性・可用性を保つことを目指します。DBMSの権限の設定は、その対策の一つです。
基本情報の範囲ここまで
レジの画面とネット予約の画面は、どちらもDBMSを通して同じ表を扱うことになりました。次に片づけるのは、表に入れる中身そのものです。
1-7データ分析
台帳を最初から読み返すと、商品の名前がばらばらでした。「食パン」「角食」「食パン(角)」は、どうやら同じパンです。一方で「食パン」と書かれた予約の中には、山型の食パンを指しているものも混じっていました。店長に聞くと、「ネットでは2本、店では2斤と書く人もいるね」と、数え方まで違うことが分かりました。
表を作る前に、業務で使うデータを洗い出し、それぞれが何を意味し、どう関わり合っているかを整理しておく作業がデータ分析です。整理しないまま表を作ると、同じ物に別の名前が付いていたり、同じ名前で別の物を指していたりする項目が、そのまま表に入ります。数えたつもりの「食パンの予約数」が、ほかのパンまで含んでいたり、一部が漏れていたりするわけです。
ここから基本情報!名前のずれと重複をなくす
意味は同じなのに名前が違う項目を異音同義語、名前は同じなのに意味が違う項目を同音異義語といいます。「食パン」と「角食」は異音同義語、店頭の「数量」が斤の数、ネットの「数量」が本の数を指しているなら、その2つの「数量」は同音異義語です。データ分析では、どちらも見つけ出して、1つの意味に1つの名前が対応するように項目をそろえます(データ項目の標準化)。
名前の付け方の決まりは命名規約として文書にしておきます。「商品の名前は正式名で書く」「数量の単位は項目名に入れる」と決めれば、これから付ける名前の表記はそろいます。ただし、すでにある2つの項目が同じ意味かどうかは、規約を決めるだけでは分かりません。項目の意味を書き出して、1つずつ見比べる作業が別に要ります。
同じ内容のデータを何か所にも持たせないようにすることをデータ重複の排除といいます。電話番号が予約のたびに書き写されていると、変わったときにすべてを直さなければならず、直し漏れが矛盾になります。冒頭の古い電話番号は、この重複から生まれていました。重複を表の分け方で取り除く方法が、この章の後半で扱う正規化です。
基本情報の範囲ここまで
名前のずれを防ぐ手として、こむぎ堂は商品に番号を振ることにしました。データ項目を、一定の規則に沿った記号や番号で表すように決めることをコード設計といいます。たとえば、先頭2文字で種類を、続く2けたで品目を表すと決め、角食を「SH01」、山食を「SH02」、クロワッサンを「CR01」とします。名前の書き方が人によって揺れても、コードが同じなら同じ商品だと分かります。規則を決めておけば、新しいパンが増えても番号を迷わずに振れます。
「SH01は角食、単位は斤」という説明は、パンのデータそのものではなく、データについての説明です。このように、データの意味・形式・作成日・作った人などを記述した、データについてのデータをメタデータといいます。スマートフォンの写真に付いている撮影日時や撮影場所も、メタデータの一例です。
ここから基本情報!メタデータをまとめて管理する
データベースの表や列の名前、意味、データ型、けた数といったメタデータを、一か所にまとめて管理する仕組みをデータディクショナリといいます。設計する人も、プログラムを書く人も、ここを見れば「数量」が何の数で、どんな値が入るかを確かめられます。項目の意味が一か所に書いてあるので、異音同義語や同音異義語を見つけるときの手がかりにもなります。
基本情報の範囲ここまで
最後に、台帳から写した中身を掃除します。データに含まれる誤り・欠け・重複・表記の揺れを見つけて直したり取り除いたりし、データの品質を高める作業をデータクレンジング(データクリーニング)といいます。「佐藤さま」と「さとう様」が同じ人なら1件にまとめ、空欄の電話番号には印を付け、全角と半角が混じった数字をそろえます。ミナトが台帳の3か月分を掃除してみると、お客さまは延べ312件の記録から、実際には187人に減りました。
1-8概念設計
掃除の済んだデータを前に、ミナトはノートに四角を3つ描き、「お客さま」「予約」「商品」と書きました。四角と四角を線で結び、線の端に「1」や「多」と書き込んでいきます。相棒は、線の両端の数字を見ながら言いました。「予約と商品の線は、両方の端が『多』になるね。そこは表にするときに一工夫いるよ」
管理したい対象を四角で、対象どうしのつながりを線で表した図をE-R図(Entity Relationship Diagram)といいます。E-R図は、どの種類のデータベースを使うかを決める前に、業務の中で何をどう結び付けて管理したいかを描くための図です。1人のお客さまが何回も予約するなら、「お客さま」と「予約」を結ぶ線の予約の側に「多」を書き添えます。
ここから基本情報!E-R図を形づくる要素
E-R図のように、業務で扱う対象とそのつながりを、データベースの種類や製品によらずに表したものを概念データモデルといいます。データモデルを作る最初の段階で、ここから論理データモデル、物理データモデルへと具体的にしていきます。
図の四角がエンティティで、人・物・出来事など、管理する対象を表します。「お客さま」「予約」「商品」は、どれもエンティティです。関係データベースでは、1つのエンティティがおおむね1つの表になります。
「お客さま」の四角が表しているのは、佐藤さまや田中さまといった一人ひとりではなく、お客さまという種類そのものです。個々のデータではなく、その集まりとしての型を表すものをエンティティタイプといい、佐藤さまのような個々の具体例はインスタンスと呼んで区別します。
エンティティどうしのつながりはリレーションシップ(関連)です。つながりの数の対応をカーディナリティ(多重度)といい、1対1、1対多、多対多のどれかで表します。「お客さま」と「予約」は1対多です。「予約」と「商品」は、1回の予約で何種類もパンを頼め、1種類のパンが何回も予約されるので、多対多になります。
関係データベースの表は、多対多のつながりをそのまま持てません。そこで、間に「予約明細」(どの予約で、どの商品を、いくつ頼んだか)というエンティティを置き、「予約」と「予約明細」、「商品」と「予約明細」の2本の1対多に分けます。相棒の言った一工夫は、このことでした。E-R図のほかに、UMLのクラス図で同じつながりを描くこともあります。
基本情報の範囲ここまで
ノートの図は、四角が4つに増えました。お客さま、予約、予約明細、商品です。
1-9論理設計
図を表に作り直していると、店長がのぞき込みました。「お客さまに番号なんて振らなくても、名前で探せばいいんじゃない?」。ミナトが掃除したデータで調べてみると、「佐藤」という名前のお客さまは5人いました。名前では、どの佐藤さまの予約なのかを1人に決められません。
関係データベースでは、データを行と列の形のテーブル(表)に格納します。表の1列ごとの項目がフィールド(項目)で、「名前」「電話番号」のように、それ以上分けて扱わないデータの単位です。いくつものフィールドをまとめた1件ぶんのデータがレコードで、表の1行にあたります。佐藤さま1人ぶんの名前・電話番号・住所がそろって、1件のレコードになります。
関連のあるレコードを集め、名前を付けて記憶装置にまとめて保存したものがファイルです。ファイルのうち、商品やお客さまのように業務の基準になり、毎日は書き換えないデータを持つものをマスタファイルといいます。商品マスタやお客さまマスタがその例です。これに対して、日々の予約や売上のように、出来事が起きるたびに増えていく記録を持つファイルはトランザクションファイルと呼ばれます。
表の中で、1件のレコードを1つに決めるために使う列(または列の組)を主キーといいます。お客さまの表なら「お客さま番号」を主キーにすれば、佐藤さまが5人いても、番号で1人に決まります。主キーの値は、表の中で重なってはならず、空のままにもできません。
ここから基本情報!主キーを選ぶときの決まり
表の中で、レコードを1つに決められる列(または列の組)は、1つとは限りません。お客さまの表では、お客さま番号のほかに、電話番号でも1人に決まるかもしれません。このように、主キーになりうる列(の組)を候補キーといい、その中から1つを選んで主キーにします。電話番号は変わることがあり、登録しないお客さまもいるので、こむぎ堂ではお客さま番号を選びました。
値が入っていない、または分からないことを表す特別な印をNULL(ナル)といいます。電話番号を教えてくれなかったお客さまの電話番号の欄はNULLにします。NULLは数値の0とも、文字が1つもない空の文字列とも違い、「値が無い」ことそのものを表します。
ある列(または列の組)の値が、表の中で重ならないことを保証する決まりを一意性制約といいます。主キーには、一意性制約に加えて、NULLを許さない決まりが付きます。電話番号の列に一意性制約を付けると、同じ電話番号で2人目のお客さまを登録しようとしたときに、DBMSが受け付けません。
基本情報の範囲ここまで
予約の表には、誰の予約かを表すために「お客さま番号」の列を置きます。このように、ほかの表の主キーの値を持ち、表どうしのつながりを表す列を外部キーといいます。予約の表の「お客さま番号」をたどれば、お客さまの表で名前や電話番号が分かるので、予約の表に名前や電話番号を書き写す必要がなくなります。
ここから基本情報!表どうしの矛盾を防ぐ決まり
データの間に矛盾が生じないよう、データベースに設定しておく決まりをまとめて整合性制約(一貫性制約)といいます。一意性制約、NULLを許さない制約、列の値の範囲を決める制約、そして外部キーに関わる制約が、その代表です。
外部キーの値は、参照先の表の主キーに実際にある値か、NULLでなければならない、とする決まりを参照制約といいます。この決まりが守る性質を参照の整合性(参照一貫性)と呼びます。予約の表に、お客さまの表に無い「お客さま番号999」が入ると、誰の予約か分からない行ができてしまいます。逆に、予約が残っているお客さまをお客さまの表から消すと、予約の外部キーが指す先がなくなります。参照制約を付けておけば、DBMSがどちらの操作も止めます(消すときは、関係する予約もまとめて消すといった別の動きを指定することもできます)。
基本情報の範囲ここまで
ミナトは、お客さま・予約・予約明細・商品の4つの表に主キーを決め、外部キーで結びました。表の形は、ノートの図のとおりになりました。それでもミナトは、これで本当に電話番号の書き写しがなくなったのかを、手順を追って確かめておきたいと思いました。
1-10データの正規化
先月、常連の田中さまが電話番号を変えました。古い台帳を写しただけの1枚の表では、田中さまの予約の行が12行あり、その全部の電話番号を直さなければなりません。ミナトが数えると、直し忘れた行が1つ残っていました。冒頭の佐藤さまの古い番号も、同じようにして残っていたのです。
1つの表に何でも詰め込むと、困りごとは電話番号の直し漏れだけでは済みません。まだ誰も予約していない新しいパンは、予約の行が無いので商品名と値段を登録できません。ある人の最後の予約を取り消すと、その行と一緒にお客さまの名前と電話番号まで消えてしまいます。どれも、同じ事実が何度も書かれていたり、関係のない事実が同じ行に同居していたりすることから起きています。
こうした矛盾が起きないように表を分け、同じ事実を1か所にだけ持たせる作業を正規化といいます。正規化した表では、電話番号はお客さまの表に1回だけ書かれ、予約の表はお客さま番号でそれを指します。電話番号が変われば1か所を直すだけで、どの予約から見ても新しい番号になります。
ここから基本情報!正規化の手順を表で追う
1枚の表で起きていた3つの困りごとを、まとめて更新時異状といいます。値を変えたときに一部だけが変わって矛盾する更新の異状、必要な事実を登録できない挿入の異状、消したくない事実まで消える削除の異状の3つです。正規化は、表を段階を追って分け、この異状を取り除いていきます。こむぎ堂の予約で、実際に手順を追ってみます。
台帳を写した形では、1件の予約の中に、頼んだパンの数だけ「商品コード・商品名・単価・数量」がくり返し並んでいます。
| 予約番号 | 日付 | お客さま番号 | 名前 | 電話番号 | 頼んだパン(商品コード・商品名・単価・数量) |
|---|---|---|---|---|---|
| 1024 | 10/17 | C07 | 田中 | 090-0000-1111 | SH01・角食・340円・2/CR01・クロワッサン・180円・3 |
| 1025 | 10/17 | C12 | 佐藤 | 080-0000-2222 | SH01・角食・340円・1 |
1つの欄に値がいくつも入るくり返しを取り除き、どの欄にも値が1つだけ入るようにした形が第1正規形です。くり返しを1行ずつに展開すると、予約1024は「SH01の行」と「CR01の行」の2行になります。行を1つに決めるには、予約番号と商品コードの組が要ります。この組が主キーです。
次の段階に進むには、関数従属という考え方を使います。列Xの値が決まると列Yの値がただ1つに決まるとき、「YはXに関数従属する」といい、X→Yと書きます。商品コードがSH01なら商品名は角食、単価は340円に決まるので、商品コード→商品名、商品コード→単価です。予約番号が決まれば日付とお客さま番号が決まり、お客さま番号が決まれば名前と電話番号が決まります。
数量は、予約番号だけでも商品コードだけでも決まらず、2つの組がそろって初めて決まります。このように、主キーの組の全体に従属し、その一部だけには従属していない状態を完全関数従属といいます。一方、商品名と単価は主キーの一部である商品コードだけで決まり、日付は予約番号だけで決まります。主キーの一部だけに従属している状態を部分関数従属といいます。
第1正規形から部分関数従属を取り除き、主キー以外のすべての列が主キーに完全関数従属するようにした形が第2正規形です。商品コードだけで決まる列を「商品」の表へ、予約番号だけで決まる列を「予約」の表へ移し、両方の組で決まる数量だけを「予約明細」に残します。この時点で、新しいパンは予約が無くても商品の表に登録できるようになります。
| 表 | 列(下線の代わりに【】で主キーを示す) |
|---|---|
| 予約 | 【予約番号】、日付、お客さま番号、名前、電話番号 |
| 予約明細 | 【予約番号、商品コード】、数量 |
| 商品 | 【商品コード】、商品名、単価 |
まだ電話番号は予約の表にあり、田中さまが予約するたびに書き写されます。予約番号→お客さま番号、お客さま番号→電話番号と従属がつながっているので、電話番号は予約番号に、お客さま番号を経由して間接的に従属しています。A→B、B→Cから生じる、AからCへのこの間接的な従属を推移関数従属(推移的関数従属)といいます。
第2正規形から推移関数従属を取り除き、主キー以外の列が、主キー以外の列に従属しないようにした形が第3正規形です。お客さま番号で決まる名前と電話番号を「お客さま」の表へ移すと、予約の表は「【予約番号】、日付、お客さま番号」になり、新しく「お客さま(【お客さま番号】、名前、電話番号)」ができます。これで、予約・予約明細・お客さま・商品の4つの表がそろいました。
基本情報の範囲ここまで
正規化した表では、田中さまの電話番号はお客さまの表の1行にしか書かれていません。番号が変わっても、直すのはその1か所です。ミナトは、ノートの図と同じ4つの表に行き着いたことを確かめて、ようやく安心しました。
1-11物理設計
表の形が決まると、店長が現実的なことを聞いてきました。「で、それを入れておく機械はどのくらいの大きさがあればいいの? クリスマスの前に、画面が重くなったりしない?」。ミナトには、すぐには答えられませんでした。
表の形が決まったら、最後にそれを記憶装置の上にどう置くかを決めます。この段階を物理設計といいます。どれだけの容量が要るか、よく使う検索が速く終わるか、といった、実際に動かしたときの心配をここで片づけます。
ここから基本情報!記憶装置への置き方を決める
論理設計で決めたデータの構造を、使うDBMSの上の具体的な表・列・格納場所に対応付けることを、基本情報のシラバスでは論理データ構造のマッピングと呼んでいます。予約明細の表を記憶装置のどの領域に置くか、よく検索する列に索引を付けるか、といったことを、ここで具体的に決めていくと考えればよいでしょう。
似た言葉のデータマッピングは、形式の違うシステムやデータベースのあいだで、互いに対応するデータ項目どうしを結び付けることです。古い台帳の「お名前」欄を新しい表の「名前」列へ、「品名」欄を商品コードへ、と対応を決めておくのがその例で、データの移し替えやシステムどうしの連携で使われます。
必要な記憶装置の容量を、レコードの大きさと件数から前もって計算しておくことをディスク容量見積りといいます。予約明細の表で計算してみます。1件のレコードを200バイト、1日に60件、1年で365日とすると、1年分は60×365=21,900件です。記憶装置は、ブロックと呼ばれる決まった大きさの単位でデータを読み書きします。1ブロックを2,000バイトとし、あとで行を足せるように各ブロックの80%までしか使わないと決めると、1ブロックに入るのは2,000×0.8÷200=8件です。21,900÷8=2,737.5なので、端数を切り上げて2,738ブロック、容量は2,738×2,000=5,476,000バイト、およそ5.5Mバイトになります。
レコードの大きさだけで掛け算すると21,900×200=4,380,000バイトですが、ブロックの空きを残す分、実際に要る容量はそれより2割以上(この例では1.25倍)多くなります。見積りでは、こうした空きや、索引などのための領域も足しておきます。
容量の次は速さです。応答時間(画面で操作してから結果が返るまでの時間)や、決まった時間に処理できる件数を測ったり見積もったりして、求められる水準を満たしているかを確かめることを性能評価といいます。「12月の予約が多い夕方でも、予約の確定が2秒以内に返る」といった目標を先に決め、試しにデータを入れて測ります。足りなければ、索引を付けたり置き方を変えたりして、物理設計をやり直します。
基本情報の範囲ここまで
翌週の土曜の朝9時。レジの前に並んだお客さまは、今度は1人だけでした。ミナトがお客さま番号を入れると、予約の表から「食パン2斤、9時受け取り」の1行が出て、お客さまの表の電話番号も先週変わったばかりの新しいものになっています。台帳の時代に「佐藤さま」と「さとう様」に分かれていた記録は、データクレンジングで1人のお客さまにまとめ、電話番号はお客さまの表の1か所だけに置きました。同じ時刻に入ったネット予約も、DBMSが在庫の行を順番に書き換えたので、残り1斤を2人に約束することはありませんでした。
店長は焼き上がった食パンを棚に並べながら、画面の4つの表を眺めて言いました。「これだけきれいに分かれているなら、先月いちばん予約が多かったパンも、すぐに分かるよね」。ミナトはうなずきかけて、手が止まりました。4つに分けた表から、どうやって一つの答えを取り出せばいいのか。その方法を、ミナトはまだ知りませんでした。