複合キーこそがDOAの中心概念のひとつである事を解説したいと思います。その前に、私がDOAにはまった経緯ついても説明します。結論は渡辺幸三氏と変わりませんが、いちSEの私はDOAをそれほど厳格にとらえていません。お叱りを受けるかもしれませんが、業務設計に役立つものとして利用させてもらってるだけです。
2-1.DOA設計手法との出会い
システム設計の手法には歴史的な経緯があります。私が入社した頃、NECにはSTEPSという設計手法とドキュメントフォーマットがセットになった方法論があり、何の疑いもなくそれを使っていました。その後、複雑な業務を設計する必要に応じて、ジャクソン法やワーニエ法を勉強し、デマルコの構造化分析にたどり着きました。構造化分析は今でも現役で使われている優秀な設計手法です。
それと並行して「DOA(データ・オリエンティッド・アプローチ)」という手法も勉強しました。昔は、製造工程を画期的に短縮するRAD(ラピッド・アプリケーション開発)という方法論とペアで語られる事が多かったです。「DOAは正しいんだけど、それだけの時間も費用もないから出来ない」と説明してくれる先輩もいました。
今から思うと、DOAではなくコッド正規形を勉強しただけでした。実際には、DOAで設計しないと時間も費用も大きくロスするのだという事が理解出来たのは十年以上先の事です。当時はそんなものかと思っていました。講師もよくわかってなかったのでしょう。こんな誤った手順を教わった記憶があります。
・テーブルを設計します
・それを正規形にします
・ER図を書きます
DOAが設計の手法だと聞いて勉強しているのに、この手順ではお絵かきの手順を教わったようなものです。正しくDOAで設計すれば第三正規形には自ずとなるのですが、そういう根本的な事も理解出来ず、DOAから離れて設計していました。
何度かトラブル案件をお手伝いして、ふと気付きました。ことごとくデータモデルを作っていないどころか、DOAをまったく知らない人が設計しているという事です。彼らは、画面と帳票のレイアウトだけでお客様と会話し、レビューしています。そのため画面個別にみると実現可能なように見えても、全体を組み上げるまで矛盾に気づきません。同じ集計項目が複数テーブルにあるので、どれを使えば良いのか聞くと「どれでもいいです」という答え。これで品質が担保出来るわけがありません。
SEとして10数年経験し、複数のプロジェクトを見るようになってから、再度DOAを勉強しだしました。勉強してわかったのは、テーブルの項目が多少漏れていても設計の中で追加すれば良いが、テーブルとテーブルの関係(リレーションシップ)が変わると大きな手戻りが発生するという事でした。つまり、大まかなデータモデルを前提にしないと見積もりの精度も納期の精度も上がらないという事です。初めてDOAを勉強してから10年以上たってようやく理解出来たと感じました。
ちなみに、「大まかなデータモデル」という曖昧な表現を使いました。本当なら概念データモデルと言いたいのですが、その言葉はDOAの世界では厳格に定義されているので使えません。個人的には「なんちゃってDOA」と呼んでました。
2-2.DOAの基本
ここで、リレーションシップという言葉の簡単な説明を行います。DOAの基本的な概念です。数学で言う関数(リレーション)は、
y=f(X)
で表せます。RDBで言うと、一つのテーブル(f)に対して、主キー(x)を与えると項目(y)が決定するという意味になります。この時、yはxに関数従属すると言います。
リレーションシップはもう少しゆるい関係を表す言葉です。日本語では「関連」と訳しますが、わかりにくいので、リレーションシップで通します。リレーション(関数従属性)は主キーと項目の関係でしたが、リレーションシップは、テーブルとテーブルの関係の事です。
項目と項目を、厳格に関数従属性で整理してテーブルを作る事がDOAの基本です。そうすれば自然と第三正規形にはなる事は理解出来るでしょう。正規形にするとテーブルの数が増えますから、いくつかのテーブルを参照しないと業務画面が作れません。リレーションシップはその関係を表した言葉です。関数従属性(正規形)から必然的に出てくるという事がおわかりでしょうか?すごく単純な事なのですが、理解して腹落ちするのはある程度業務設計の経験が必要です。
売上ヘッダに売上明細が複数あるようなとき、「売上TBLと売上明細TBLのリレーションシップは1:多である」という言い方をします。テーブルは次のような形になるでしょう。
TBL 項目({ }は主キー)
売上 :{売上No}、顧客CD、年月日・・・
売上明細:{売上No、行No}、商品CD、商品単価、数量・・・
商品 :{商品CD}、商品名、商品単価・・・
売上明細TBLの中に「商品名」はありません。商品CDをキーとして商品TBLを検索すれば見つかるためです。売上明細TBLと商品TBLの間にも多:1のリレーションシップがあります。売上明細に商品単価があるのは正規化違反でしょうか?確かに商品テーブルにも商品単価があるので参照出来ます。これには2つの意味があります。
1) 商品テーブルの商品単価を初期表示するが売上画面で単価を変更出来る
2) 単価の変更にそなえて、売上時点の値(スナップショット)を持っている
正統派のDOAの方なら項目名を変えるべきだと言われそうですが、現場はあまり気にせず「商品単価」とする事が多いでしょう。
DOAのリレーションシップは、異なるテーブルに同じ項目(この例では売上Noと商品CD)がある事で把握出来ます。リレーションシップを線で表したものをデータモデル図と呼びます。線を引かなくても項目を見るだけでリレーションシップを把握出来るような気がしますが、その通りです。データモデル図は、リレーションシップだけでなく処理の順序やテーブルの性質など、付随する情報を盛り込んで作図します(DOAの流派によって多少差異があります)。
リレーションシップの基本パターンは「親子関係」、「参照関係」、「派生関係」の3つしかないと渡辺幸三氏の「業務別データベース設計のためのデータモデリング入門」に書いてありました。この本は初心者の方には少し難しいですが、DOAの考え方だけでなく様々なテクニックやDOAの可能性をストレートに表現されている良書です。グラス片手にされる前に読まれる事をお勧めします。
2-3.複合キーの必要性
業務上の項目自体を主キーとする実装方法を「自然キー」と呼び、別の順次番号などを主キーとする事を「人工キー(または代理キー)」と呼びます。売上明細のように、主キーに複数の項目を持つことが「複合キー」です。
上で説明したとおり、複合キーはDOAの基本概念とも言えます。
1)DOAの基本は、関数従属性とリレーションシップです
2)リレーションシップとは、複数のテーブルが同じ項目を持つことで示されます
3)親子関係など主キーに関連項目を持つ場合は複合キーとして現れます
代理キーを付けるなら複合キーにする必要はありませんが、2つのテーブルの代理キーを組み合わせた複合キーは必要です。オブジェクト指向派の方は、クラウスとクラスの関係はオブジェクト自体で保持するのでしょうが、データベースで表せるものはデータベース自体で表すことで、業務全体の見通しが良くなります。
DOA設計の実装にとって複合キーは必須だということにガッテンして頂けたでしょうか?