楽々ERDレッスンでの学び

はじめに

今回は楽々ERDレッスンを読み学んだことを記していきます。
本書序盤はこれまで学んできたこと(キーとはなにか、エンティティとは何かなど)をビジネスの視点からより業務に近い形で説明がされております。
全体を通じて感じたのはデータベース設計で行う正規化はそれ自体が目的ではなく、あくまで手段であるということ。その業務・ビジネスの目的にそったデータベース設計を心がけることが大切なのかと感じました。正規化が目的化してしまうと厳格な正規化のルールを順守することに注力して、それを使う時の利便性や分かりやすさを損ねてしまう可能性があるので注意する必要があります。

序盤は私には難しいながらも読み進めていけましたが最も唸ったのは「実在する帳票からデータベース設計を行う」という箇所でした。
先の勉強で多少正規化の作法が分かってきたかなと思っていましたがとんでもなかったです。以下では私がやってみたデータベース設計と、それがどう不味かったのかを記していきたいと思います。著作権が怖いので、不味い箇所があればご指摘いただければ幸いです。

図書館の予約申込書編

images.app.goo.gl

以下は私がやってみた方法とテーブル設計になります。
1.この用紙の目的を検討する
「借りたい本の予約申し込みを行う」としました。
2.エンティティを抽出して主キーを追加する
Image from Gyazo

3.外部キーを設定しリレーションを組んでいく
Image from Gyazo

このように考えたのは貸出券に「誰が」「どの本を予約して」「どうやって受け取るか」という情報を付随させた方が良いと考えたからです。

では書内ではどのようなデータベース設計を行なっているか

書内では違ったデータベース設計を行っていました。これに私も納得したので気づきと共に記していきます。

まずは、最初の核となるエンティティの抽出から。書内では予約テーブルを抽出しています。
これは図書の予約申込書の目的が予約することなのだから当然です。私も目的を検討していましたがそれをエンティティとして抽出することに活かせていませんでした。
Image from Gyazo

これをイベント系エンティティの抽出と呼びます。特徴としては「〜する」「〜日」と付けることができる点です。「予約する」「予約日」共に違和感ないので問題ないようです。
更にエンティティを抽出していきます。次に行うのはリソース系エンティティの抽出です。リソース系とは資産であることを指します。
今回でいえば「書籍」と「予約者」が当てはまります。予約書の発行者である図書館にしてみれば「書籍」は商品、「予約者」は顧客と考えることができ大切なリソース(資産)であることは間違いありません。(この考え方は本書を読むことで初めて意識しました。覚えておきたい考え方です。)
これで以下のエンティティができました。
Image from Gyazo

この後はエンティティに項目(カラム)を入れていきますが、私が考えていたものと随分異なりますので一つ一つ確認しながら進めていきいます。
まずは予約者エンティティに項目を入れます。
Image from Gyazo

ここで早速私の作成した予約者テーブルと異なる点があります。まずは「ふりがな」が入っている点。これは私が勝手に名前カラムと同一視していましたが、用紙にはきちんと「ふりがな」「名前」とそれぞれ記入する箇所ありますのでカラムとして入れるべきでした。
次に、予約者エンティティに「貸出券番号」が入っている点。私は貸出券テーブルを作成してそこに入れてましたが、書内では先程挙げたように「予約」「書籍」「予約者」をエンティティの主軸としておりますのでこの中で「貸出券番号」がどこに入るかを検討します。(どこにも入りそうにない場合はエンティティが不足している可能性あるので無理に入れる必要はありませんので注意
書籍エンティティは書籍の内容が入るので除外するとして、予約エンティティはどうでしょうか?私としては最初このエンティティに入るのかと思いましたが、予約エンティティには予約の仕方・詳細が入るのだと考えると「貸出券番号」は少し違和感です。それよりも予約者エンティティに入れる方が良い気がします。感覚としては①貸出券番号は予約者に振り分けられる。②貸出券番号で予約者を判別するという点で他の名前・ふりがなカラムと同様の意味を持つ。
この辺の感覚で貸出券番号が予約者エンティティに入れられるのかと考えました。

次に書籍エンティティに項目を入れます。

Image from Gyazo

ここでも私のテーブル設計と異なる点を見ていきます。
まずは価格のカラムが抜けていた点。これは私の見落としでしたので観察が足りませんでした。
次に出版社が別エンティティとして切り出されている点。これには驚きました。書内では商品カテゴリのようなものとして別エンティティに切り出したとあります。
ですが、私がこれまで学んできた正規化を行う際の検討事項である「1つのカラムには1つの値」「部分関数従属の解消」「推移的関数従属の解消」から考えると、今回の出版社エンティティの切り出しはどれにも当てはまらないように思えたのです。
実はこの後の補足で「出版社をただのメモ書き程度と考えるのであれば書籍エンティティに持たせるのも良い」とあるので必ずしも出版社を別エンティティとして切り出す必要はないのが分かります。
ここで大事なのは冒頭でも述べてるように、正規化はあくまで手段であるということ。その業務・ビジネスの目的にそったデータベース設計を心がけることが大切であるということです。これを踏まえた上で出版社を別エンティティとして切り出すのかを判断すべきです。

次に予約エンティティに項目を入れていきます。残るは申込日、連絡方法、電話番号、ご家族に書名を伝えて良いか、受け取り希望館またはみどり号ステーション、この本を何で知りましたか。になります。何が入るでしょうか?(ちなみにみどり号ステーションとは移動図書館のことです)
書内では以下のように設計しています。

Image from Gyazo

申し込み日がここに入るのは違和感ありません。書名伝達可否は用紙の「ご家族に書名を伝えて良いか」を言い換えたものです。予約の詳細を入れたいのでこれも良いと思います。
では図書館エンティティはどうでしょうか。これは予約した本の受け取りを複数ある図書館のどこで行うかを選択させるということで別に切り出しています。ここから学べるのは複数の選択肢があり、そこから選択する場合は別エンティティで切り出してみるということです。

さて、ここでとあることに注目します。それは連絡方法(方法と電話番号)がまだ登場していないことです。私はノータイムで連絡方法と電話番号を予約者エンティティに含めました。ですが先の図書館の例を見るに連絡方法も選択式である以上、別エンティティに切り出した方が良さそうです。
では、電話番号はどうでしょうか?書内では以下のように設計しております。

Image from Gyazo

この考え方(連絡方法と番号を別エンティティでそれぞれ切り出した)のポイントは予約者がいつも同じ連絡方法と電話番号を選択するかということだと思います。
いつも同じ方法、同じ電話番号でというのが確定しているのであればこれらは予約者エンティティに含めて良いと思います。ですが逆にいつも同じ連絡方法・電話番号とは限らない場合は「予約者は複数の連絡方法・電話番号を持つ」というように考えることができるのです。
また、ここで予約エンティティに「連絡不要区分」というのが新しく含まれていることに気づきます。これは用紙の連絡方法の中の選択肢の一つ「不要」という項目を表したものです。これがなぜ連絡方法エンティティと離れ、予約エンティティに入るのかを考えます。
そもそも何故予約したにも関わらず連絡不要とする可能性があるのでしょうか?
注目すべきはこの用紙のタイトル「予約(リクエスト)申込書」にあります。これはこの用紙の目的が
①依頼した本の予約が空いたら次に借りるから知らせてほしい(予約)
②こんな本があったら良いのではないか、置いてほしい(リクエスト)
の2つが存在することを意味します。②のリクエストの方は確かに本を取り寄せたとしても連絡は不要という人もいるかもしれません。そうすると予約者のところは記入が不要ではないかとの考えも出てきます。となるとこの連絡不要区分は予約の内容(予約なのかリクエストなのか)を明示するひとつの項目となりますので予約エンティティに入れることになると思われます。

最後に、「この本を何で知ったか」という項目について考えます。
これは私も「本情報取得情報エンティティ」として切り出していましたので少し安心しましたが、書内では「知った」というエンティティにしていました。
私はこれを貸出券エンティティに外部キーとして関連づけておりましたが、書籍をどのように知ったのかは人により異なるので書籍と予約者両方のエンティティに結びつくのが正解であると思われます。

最終的なテーブル間のリレーションシップ

Image from Gyazo

いかがでしたでしょうか。一番最初に完成系のER図を見ても理解が難しいかもしれませんが、一つ一つ順を追って見ていくと意外と理解できるのではないでしょうか?
私が最初に作成したものと比較すると複雑ですが、より業務内容に即したものであることが分かります。「予約する」という目的にも沿ったものであることも理解できます。
その点で私のやったことは目的が分からず良くないことが分かり、反省するばかりです。
今回の流れから正規化を目的とするのではなく業務・目的に沿ったデータベース設計が大切であることが実体験を持って知ることができました。
この他にも書内にて日常生活で遭遇する事象のデータベース化が記してありますので、読み返しながらより理解を深めていきたいと思います。

www.shoeisha.co.jp