はじめに
システム構築においてデータベース設計は不可欠です。そこで多くの方がデータベースの設計技法について書籍で学んだりするのですが、なかなか身についたと感じられないことも多いのではないかと感じます。
その理由は、実務で任せられる機会というのが少ないからというのが大きなものとして挙げられます。データベース設計というのは、やはり重要な箇所ですから自然と経験のある人に任せられることが多いのが実態です。しかもデータベース設計を担当するのはプロジェクト全体の中でもごく少数だけになりますから、なかなかチャンスが巡ってきません。
しかし、それを嘆いているばかりではスキルが身につかないのも道理です。そこで身近にあるものを何でも手当たり次第にデータベース設計のネタにしてしまうことで、コツコツと地力をつけていこうというのがこのシリーズの主旨です。
合言葉は、「表組みを見たらERDを描け!」 。では、張り切って行きましょう。
対象読者
データベース設計の初心者~中級者。
必要な環境
以下のいずれかのRDBMS。
- PostgreSQL 8.0以上
- MySQL 4.0以上
- HSQLDB 1.7.2以上
- MaxDB 7.5以上
- Oracle 10g以上
- SQL Server 2000以上
題材
今回の題材は、あるファミリーレストランのテイクアウト用注文用紙(図1)です。みんなで食事に行った際にテーブルの上に置いてあったので早速利用することにしました。このように身近なものをスラスラとデータベース設計できると、きっとカッコ良く見えること間違いありません(?)。お馬鹿な話はさておいて、ではデータベース設計のはじまりです。
イベントを見出す
まずは核となるテーブルを見出しましょう。そもそもこの紙は何のためのものでしょうか。そう、注文を受け付けるためのものです。つまり「注文」という情報が核になります。ですからまずは「注文」テーブルを用意します(図2)。なお、表記法はIDEF1Xを使います。
![図2 「注文」テーブル 図2 「注文」テーブル](http://cz-cdn.shoeisha.jp/static/images/article/154/fig02.gif)
さて、注文というのは行為です。もう少し具体的にいうと「~する」という言い方が出来ます。今回ですと「注文する」という表現が成立します。このような行為の記録となるものを「イベント(出来事)系」のテーブルと呼んだりします。
イベント系には他にも、出荷であったり入金であったり様々なものがあります。いずれも「~する」という表現が成立します。実はこのイベントの連鎖によって、商売・ビジネスは成り立っています。イベントは何か、ということに注目する癖をつけることで、色々なことに対して目が利くようになります。
リソースを抜き出す
さて、注文するといっても、注文が単独で存在するわけではありません。最低限、何を注文するのかがわからないといけませんし、誰が注文するのかがわからないとお届けも出来ません。このような観点でもう一度用紙をじっと見ると、「誰が」「何を」ということについての記載があります。「誰が」というのは用紙の一番下にある「お名前」がそれに該当します。また、「何を」というのはたくさん並んでいる商品名が該当します。そこでこれらを登録するために、それぞれにテーブルを用意しましょう。「顧客」テーブルと「商品」テーブルとします(図3)。
![図3 図3](http://cz-cdn.shoeisha.jp/static/images/article/154/fig03.gif)
ここで「顧客」テーブルや「商品」テーブルが現れたわけですが、「~する」という表現は成立するでしょうか。「顧客する」「商品する」……いずれも変です。日本語として成立していません。よってこれらはイベント系とはいえないということになります。では、これらは何と呼べばいいでしょうか。これらは商売・ビジネスを行う上で重要な資産であるといえます。そこで、これらを「リソース(資産)系」と呼びます。
リソース系は得てして複雑なデータ構造を持っていたりします。いきなりこれを綺麗に設計しようとすると大変なので、まずはイベント系から洗い出してその後じっくりとリソース系について考えていくほうが、結果として精度の高い設計を実現できます。
項目を入れていく
箱を用意したら、それぞれに項目を入れていきましょう。まずはわかりやすいところからということで、「顧客」テーブルから埋めてしまいましょう(図4)。余計なことは考えずに、見た目の通り素直に項目を入れていきます。
![図4 図4](http://cz-cdn.shoeisha.jp/static/images/article/154/fig04.gif)
次に注文テーブルも埋めてしまいましょう。注文に関わるものは「ご注文数」ですので、これを「注文」テーブルに入れてしまいます(図5)。
![図5 図5](http://cz-cdn.shoeisha.jp/static/images/article/154/fig05.gif)
さて、最後に「商品」テーブルになるのですが、慌てずに順番に項目を入れていきましょう。まずは、商品名と金額はハッキリしていますのでこれを「商品」テーブルの項目にしてしまいます(図6)。
![図6 図6](http://cz-cdn.shoeisha.jp/static/images/article/154/fig06.gif)
ここでさらにじっくりと見ると、金額はカッコつきで税込が書かれています。これについては「税率」テーブルを持たせて演算で求めるのかなどということを思いついたりして悩ましいところですが、まずは見た目の通りに素直に項目化しておきます。また、商品名の頭に「NEW」という文字が入っている商品が幾つかあります。きっと新商品なのでしょう。この見分けをつけるために商品区分を追加しておきましょう(図7)。
![図7 図7](http://cz-cdn.shoeisha.jp/static/images/article/154/fig07.gif)
ここまで来たらほぼ出来上がりのように感じるのですが、よくよく見てみると気になるものが残っています。「お持ち帰り弁当」とか「一品料理」などのように、複数の商品名を括っている、いわばグループ化している項目があります。そこで商品カテゴリを表すためのテーブルをひとつ追加しましょう(図8)。
![図8 図8](http://cz-cdn.shoeisha.jp/static/images/article/154/fig08.gif)
リレーションシップを設定する
ここまで出来たら、後はテーブル間のリレーションシップを設定するだけです。リレーションシップを設定するには主キーが必要になります。しかし主キーに意味を持たせてしまうと、その項目の意味付けを変えたくなったときにリレーションシップの意味まで変わってしまい困ることになります。そこで無機質な識別子を導入して、それをあたかもポインタのごとく使って参照関係を設定していきます。
まずはそれぞれのテーブルに識別子(Identifier)を導入します。単純にテーブル名+IDという項目名にしてしまいましょう(図9)。
![図9 図9](http://cz-cdn.shoeisha.jp/static/images/article/154/fig09.gif)
IDを設定したら、テーブル間の関係を指定していきます(図10)。
![図10 図10](http://cz-cdn.shoeisha.jp/static/images/article/154/fig10.gif)
これでこの注文用紙のデータベース設計は完了です。後はそれぞれの項目のデータ型を指定していけばOKです。今回は、数値項目はINTEGER
に、文字列は全てVARCHAR(100)
にしてありますが、必要に応じて色々と試してみてください。
SQLはこうなる
出来上がったデータベース設計は、そのままほったらかしていては意味がありません。そこで実際にデータベース上にテーブルを作成してみましょう。SQLは次のようになります。
CREATE TABLE 商品カテゴリ ( 商品カテゴリID INTEGER NOT NULL, 商品カテゴリ名 VARCHAR(100), PRIMARY KEY (商品カテゴリID) ); CREATE TABLE 商品 ( 商品ID INTEGER NOT NULL, 商品名 VARCHAR(100), 金額 INTEGER, 税込金額 INTEGER, 商品区分 INTEGER, 商品カテゴリID INTEGER NOT NULL, PRIMARY KEY (商品ID), FOREIGN KEY (商品カテゴリID) REFERENCES 商品カテゴリ (商品カテゴリID) ); CREATE TABLE 顧客 ( 顧客ID INTEGER NOT NULL, お名前 VARCHAR(100), お電話番号 VARCHAR(100), PRIMARY KEY (顧客ID) ); CREATE TABLE 注文 ( 注文ID INTEGER NOT NULL, ご注文数 INTEGER, 商品ID INTEGER NOT NULL, 顧客ID INTEGER NOT NULL, PRIMARY KEY (注文ID), FOREIGN KEY (顧客ID) REFERENCES 顧客 (顧客ID), FOREIGN KEY (商品ID) REFERENCES 商品 (商品ID) );
自由にレコードを追加して、色々なSELECT文を試してみてください。
Orders T_ORDER CHUMON ODR_TBL ...
一歩先読みをする
さて、ここまででもデータベース設計をしましたと言って十分に通用するものになっていますが、実務レベルで考えるともう少し先手を打っておくのも悪いことではありません。
まず、注文の日時がどこにもありません。やはり、いつ注文されたのかがわかるほうがいいですね。そこで注文日時を項目として追加しておくといいでしょう。
また、新商品だけではなくてお薦め商品も表示したくなるかも知れません。それに対応するために複数の区分を導入することも考えられます。
これらを組み合わせた設計が図11になります。ここで少し意識していただきたいのは、テーブルが追加されたり項目が追加されても基本的なリレーションシップには一切変更が加えられていないことです。それぞれのテーブルの構造が安定している証拠です。実はこれを実現できている理由が識別子の導入です。レコード間の参照関係と項目の値そのものとは別であるということです。この辺りにも慣れていただけると、ぐっとデータベース設計の敷居が低くなります。
![図11 図11](http://cz-cdn.shoeisha.jp/static/images/article/154/fig11.gif)
おわりに
いかがだったでしょうか。今回の題材であれば用紙を見てから設計完了まで1分が目安です。ツールに向き合ってあれこれ書くのを含めても3分から5分程度で、CREATE TABLE
を実行できるようになるのが理想です。もちろんその場合はSQLの自動生成をしてくれるERDツールを使うのが大前提です。とはいえ、紙にラフで書くとしてもやはり5分以上かかるようでは、実務では心もとないといえるでしょう。今回の例のように、身の回りにある題材を使えばいくらでもデータベース設計のスキルをつけていくことは可能です。是非とも日々の生活の中に少し工夫を取り入れることで、楽々データベース設計をこなせる基礎体力を身につけていただければ幸いです。ではまた。