第1回がかなり読まれていたので、感激しています。ありがとうございます。
この記事を書こうと思ったきっかけは、いくつかあるのですが、特に1年半前に友人が携わっていたJavaのプロジェクトで、定義されていたデータベーススキーマを見せてもらいびっくりしたことがトリガーとなっています。そこには社員というテーブルが定義されていましたが、なんと300近い列が用意されていたのです。それはWebアプリケーションでしたが、なぜに社員のデータを扱うのに300列も必要なんでしょう。その友人いわく、「本当は正規化したいんだけど、発注元がこの仕様でないと困る」とのこと。「これはアプリケーション作成するの大変だよね」と私が問いかけると、「その通りなんです。しかも特定の列を画面上、行に変換しなければならないんです!」二人して苦笑するほかありませんでした。
皆さんはこのような変わったデータベースに触れた経験はありませんか。
さて、第2回を書くにあたり、前回の問題を振り返ってみましょう。事前に「多対多の分解とライフサイクル」の記事をお読みいただけると理解しやすいかと思います。
・・・
問題1:[人]と[会社]の[雇用契約]をベースに[社員]を定義するとどのようになるでしょうか。
問題2:このデータベースを人事部が利用するとして、その[社員]がどのように部署を移動したのか履歴をトラッキングするにはどうしたらいいのでしょうか。
問題3:このデータベースを人事部が利用するとして、その[社員]がどのように役職上、昇格(あるいは降格)したのか履歴をトラッキングするにはどうしたらいいのでしょうか。
問題4:[社員]が結婚し、苗字が変更になりました。でも社内では旧姓のままその人を管理したいと考えています。どうすればいいでしょうか。
問題5:[社員]に子供が生まれ、扶養家族が増えました。どのように管理したらいいでしょうか。
問題6:[社員]のレポート先(報告先上司)が二人以上存在するとします。どのように管理したらいいでしょうか。
・・・
まず、最初に注意したい点として、この問題を解くために完全な解は存在しません。完全な解というのは、絶対的なモデルを意味しています。その理由は、アプリケーションが目的を達成していれば、内部データはどうなっていてもいいという考え方があるからです。「それじゃあ、意味ないでしょう!」という声が聞こえてくるかもしれません。しかし、この記事では、意図的に多対多の関連をテーマに取り上げて、この問題にアプローチしてみたいと思います。
問題1:[人]と[会社]の[雇用契約]をベースに[社員]を定義するとどのようになるでしょうか。
(図1)まず、人と会社の雇用契約を考えると・・・
人 雇用契約 会社
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 会社ID(PK) |
+--------------------+ | 会社ID(FK) | +--------------------+
| ・以下省略・・ | | 契約締結日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 契約終了日 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
企業によっては、必ずしもこのモデルが適用できないケースがあります。たとえば、いったん退職した人は、二度とその会社に社員として入れない場合がそれです。ただし、社員として入れなくても「契約社員」としては入れる場合があります。それを踏まえると、会社と人との雇用契約は複数になる可能性があります。
次に問題となるのは、社員を識別する番号です。社員コードや社員番号と呼ばれるものです。これをどこに管理すればいいでしょうか。
(図2)雇用契約に社員番号を入れてしまうと・・・
人 雇用契約 会社
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 会社ID(PK) |
+--------------------+ | 会社ID(FK) | +--------------------+
| ・以下省略・・ | | 契約締結日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 契約終了日 | | |
| | | 社員ID | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
これはこれで、問題ないような感じを受けます。しかし、業務上の理由で、社員番号の管理体系が変わってしまったらどうなるでしょう。新・旧の社員番号が業務上必要になったらどうするのでしょうか。
(図3)社員と雇用契約を分離してみたら・・・
人 雇用契約 会社
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 会社ID(PK) |
+--------------------+ | 会社ID(FK) | +--------------------+
| ・以下省略・・ | | 契約締結日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 契約終了日 | | |
| | | 社員ID(FK) | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
|
社員 ●
+--------------------+
| 社員ID(PK) |
+--------------------+
| 人ID(FK) |
| 会社ID(FK) |
| 契約締結日(FK) |
| 社員ID発行日 |
| ・以下省略・ |
+--------------------+
ここでは、社員番号がユニーク(一意)であると仮定しています。雇用契約と社員の間の関連が、少しすっきりしないような気がします。
(図4)社員と雇用契約を関連とみなしたら・・・
人 雇用契約 会社
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 会社ID(PK) |
+--------------------+ | 会社ID(FK) | +--------------------+
| ・以下省略・・ | | 契約締結日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 契約終了日 | | |
| | | 社員ID | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
|
社員対雇用契約 ●
+--------------------+
| 人ID(FK) |
| 会社ID(FK) |
| 契約締結日(FK) |
| 社員ID(PK) |
| 社員ID発行日 |
+--------------------+
| ・以下省略・ |
+--------------------+
●
社員 |
+--------------------+
| 社員ID(PK) |
+--------------------+
| ・以下省略・ |
+--------------------+
ここで疑問がわいてくると思います。「人と社員は何が違うんだ」、と。
ここが関連の面白いところであり、難しいところだと思います。
皆さんも自分自身の生活を考えてみてください。個人としての自分、会社員としての自分、何らかのコミュニティに参加している自分。同じ「人」ですが、参加する「場所」が異なると「役割」が異なってきます。しかし、このモデル、日本にはあまり向かないかもしれません。なぜなら、国民に識別番号が振られているわけではないからです。
次の問題を考えて見ましょう。
問題2:このデータベースを人事部が利用するとして、その[社員]がどのように部署を移動したのか履歴をトラッキングするにはどうしたらいいのでしょうか。
ここでは、部署への配属を契約だと考えてみればよろしいかと思います。
(図5)社員と部署の関連を考えると・・・
社員 社員対部署 部署
+--------------------+ +--------------------+ +--------------------+
| 社員ID(PK) | | 社員ID(FK) | | 部署ID(PK) |
+--------------------+ | 部署ID(FK) | +--------------------+
| ・以下省略・・ | | 配属日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 配属終了日 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
問題3:このデータベースを人事部が利用するとして、その[社員]がどのように役職上、昇格(あるいは降格)したのか履歴をトラッキングするにはどうしたらいいのでしょうか
(図6)社員と役職の関連を考えると・・・
これも問題2と同様です。役割を関連で考えればいいかと思います。
社員 社員対役職 役職
+--------------------+ +--------------------+ +--------------------+
| 社員ID(PK) | | 社員ID(FK) | | 役職ID(PK) |
+--------------------+ | 役職ID(FK) | +--------------------+
| ・以下省略・・ | | 人事発令日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 役職終了日 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
問題4:[社員]が結婚し、苗字が変更になりました。でも社内では旧姓のままその人を管理したいと考えています。どうすればいいでしょうか。
人生、いろいろで、名前が変わったり、苗字が変わったりすることがあります。
人が複数の名前を持つということをどうしたらいいでしょう。
(図7)人と社員の関連を考えると・・・
人 社員の名前 社員
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 社員ID(PK) |
+--------------------+ | 社員ID(FK) | +--------------------+
| ・以下省略・・ | | 登録日 | | 社員名登録日(FK) |
| |--●+--------------------+●--| |
| | | 名前 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
不気味な感じがするかもしれませんが、社員という「場」での名前を管理する一つの方法だと思います。「同じ名前だったら再利用したらいいんじゃないの」という声が聞こえてきそうです。あまり実用的ではないかもしれませんが、やってみましょう。
(図8)ここまでくると???・・・
人 社員の名前 社員
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 社員ID(PK) |
+--------------------+ | 社員ID(FK) | +--------------------+
| ・以下省略・・ | | 登録日 | | 現社員名登録日(FK)|
| |--●+--------------------+●--| |
| | | 名前ID(FK) | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
| ●
人の名前 ● 名前 |
+--------------------+ +--------------------+
| 人ID(FK) | | 名前ID(PK) |
| 名前ID(FK) | +--------------------+
| 登録日 |●--| 氏名(漢字) |
+--------------------+ | 氏名(ふりがな) |
| ・以下省略・・ | | ・以下省略・・ |
+--------------------+ +--------------------+
問題5:[社員]に子供が生まれ、扶養家族が増えました。どのように管理したらいいでしょうか。
関連使えば簡単ですよね。
(図9)社員と扶養家族の関連を考えると・・・
人 扶養家族 社員
+--------------------+ +--------------------+ +--------------------+
| 人ID(PK) | | 人ID(FK) | | 社員ID(PK) |
+--------------------+ | 社員ID(FK) | +--------------------+
| ・以下省略・・ | | 扶養開始日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 扶養解除日 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
人生いろいろ、扶養家族から離れたと思ったら、また扶養家族になるケースもあるので・・・。
問題6:[社員]のレポート先(報告先上司)が二人以上存在するとします。どのように管理したらいいでしょうか。
もはや説明は不要でしょう。
(図10)複数の上司へレポートする場合・・・
社員 上司対部下 社員(上司として)
+--------------------+ +--------------------+ +--------------------+
| 社員ID(PK) | | 社員ID(FK) | | 社員ID(PK) |
+--------------------+ | 上司ID(FK) | +--------------------+
| ・以下省略・・ | | 登録日 | | ・以下省略・・ |
| |--●+--------------------+●--| |
| | | 終了日 | | |
| | | ・以下省略・・ | | |
+--------------------+ +--------------------+ +--------------------+
・・・
長くなりましたが、いかがでしょうか。ある「モノ」は、特定の「場」に参加すると新たな「役割」が生まれます。この観点で関連を使ってモデルを考えると、一見簡単に思えた情報管理が関連の塊でできていることに気が付くはずです。現実の事象は動的に変化します。しかしながら、データベースというものは、たいていの場合、発生した過去の事象を記録する媒体になるわけです。事象はイベントであり、状態の変化です。
「社員マスタという不思議なエンティティ」、この記事において、私は「社員マスタ」というテーブルがいきなり定義されることに反対しているわけではありません。期の締めごとに社員台帳という形でスナップショットを取って管理するというのもありかと思います。また1枚の社員台帳に修正液を使って変更のたびに修正する(SQLでいうところのUPDATEステートメントの実行)、というのもありでしょう。
問題は、後になって時系列で情報を分析したいときに、履歴が残っていないと困る、ということです。ビジネスインテリジェンス(業務上の意思決定を支援する経営情報の算出)を実現する上には、履歴データが不可欠です。売り上げとか在庫(数量または金額)といったものは履歴を残すということにあまり違和感を覚えないと思います。ここで私が提唱したいのは、一見履歴情報が不要に思えるデータも関連を考えると、とたんに履歴を残したほうが後で活用しやすい、ということです。統計、OLAP、ディシジョンツリー、相関行列、ニューラルネットワークなどビジネスインテリジェンスに対しては、関連情報が役立つと思います。たとえば、社長が「売り上げTOP10の営業マンの今までの役職上の経歴を知りたい、またその営業マンの上司の経歴を知りたい」と考えたとします。履歴データが存在しなければ、これを調べるのは大変です。しかし、上述のように関連で履歴が残っていれば、そんなに苦労することなく目的の情報を入手することができます。
最後に、あえて、完全なモデルを示していないのがこの記事のポイントです。
いきなり業務に適用するのは難しいかもしれないので、まずは頭の体操と思って、現在取り組まれている業務システムのデータの関連を見つけることからはじめてみませんか。データベースをはじめたばかりの人であれば、きっと、今まで見落としていたことに気がつくことでしょう。
ここまでお読みいただき、ありがとうございます。