[DBデザイン#12] 実例から考える: データの関係を解きほぐす

実際に納品書を見ながら何を考えればいいのかを紹介しましょう。再掲になりますが、こういう納品書があるとします。典型的な営業で使われるような書類です。

まず、下半分は都合よく表になっています。表になっているものは、1つのまとまった単位とします。この表には名前がついていないので、ここでは「販売明細」と名前をつけましょう。表になっているので、もちろん、行が複数ありますが、多分、1行以上、レイアウトが許す多数の行数があり得るでしょう。まさに、この行はレコードになりそうです。そうなると、商品名、単価、個数、金額という4つのフィールドは、販売明細のフィールドと扱えるということになります。このように、すでに表として形成されているものは、すでにデータの関係性をそこに表現しているとも言えます。

ところが、表の下の方に、合計、消費税、請求額とあります。表の中だから「販売明細」の仲間でしょうか? 確かに、これらの金額は、販売明細の表の中にある数値、つまり、金額等の合計で求められるので、確かに関係はありそうです。ですが、データベースの設計をするときに考えるのは、それらのデータの存在そのものが、他のデータとどのように関連があるかです。ここで、合計などの数値は、1つの納品書について1つ存在します。納品書ごとにおそらくは違うでしょうけど、1つの納品書に2つの合計値があるということは理屈の上では成り立ちません。つまり、合計、消費税、請求額は、納品書と1対1の関係にあります。一方、合計などと販売明細の関係は、1対多の関係になります。販売明細に存在する複数の行と、その合計の間では、前者は1つかもしれないし、50個かもしれません。それらから、1つの合計という数値が得られるので、多対1の関係になるのです。

このように、データの存在あるいは成り立ちが、他のデータとどのように関係するのかを考えます。納品書の日付は、納品書に対して1つだけなので、納品書と日付は1対1の関係にあります。

一方、顧客名が見えています。これも納品書に対して1つだけ書かれているので、納品書と1対1の関係かと思うところですが、ここでさらに、図にあるような納品書が現実には多数作られるということを考えます。つまり、納品書が1枚作成できるのはもちろん基本機能としては必要ですが、要求を満たすには、納品書は多数、そして内容が異なるものを作らないといけなくなります。そうすると、当然考えられる一つの結論としては、1つの顧客に対して何度も出荷することになるのですから、実は顧客名と納品書は1対多の関係になります。つまり、1社に対して長い年月を経ることで、多数の納品書を作成するということになります。

ここで、多数の納品書を考えたとき、納品書と販売明細の関係が1対多ではなく、多対多になぜならないのかという疑問もあると思います。だんだん説明が込み入ってきますが、頑張りましょう。まず、結論を言えば、1対多の関係が1つの納品書で完結しているので、多対多の関係にはなりません。ここでは「販売明細」がどんな性質のものかを考えて、その結論が導き出されます。販売明細は、商品、単価、価格、金額を保持している表です。ここで、ある会社に「ロボットいか2号、800円を5個、即ち4,000円の出荷をした」という情報が1行書かれているとします。しかしながら、現実には、こうした営業活動を多数行うので、販売明細の表には別の会社に対して同様にロボットいか2号を5個出荷という一見すると全く同様な情報が登場しそうです。これはいいのでしょうか? 実際に、こうした販売明細を表に記録、つまりデータベースに記録するときには、データ上は同一の出荷情報であっても、異なる納品書に書かれたものは別々のものとみなします。言い換えれば、販売明細の各行は、実物では顕在化していなかったとも言える「どの納品書にその明細が記録されているのか」という情報を付加することで、1枚1枚の納品書で1対多の関係が完結するようになっているので、それらが集まっても、1対多の関係であるとみなすのです。

ここで商品についても同じように考えたいのですが、それは次回としましょう。まずは、「納品書」と「販売明細」の2つの表に分解し、それらの結合を明示するために、納品書IDというフィールドを割り当てます。これも、以前に説明したものと同じですが、ここではまず、納品書側の納品書IDに301, 302…と先に番号を振ることとします。そして、その納品書に所属する販売明細の行について、すでに降った納品書IDの値を記入します。つまり、以下の図では、販売明細の最初の2行が、納品書の最初の1行に対応し、販売明細の3, 4, 5行目が納品書の2行目に対応します。つまり、同じ納品書IDのもの同士が組み合わされて、1枚の納品書になるという状況を作ります。

顧客や商品についての議論も必要でし、「販売明細の金額は計算で導き出せるよね」みたいな話もしなければなりませんね。また、右の方にER図なんかが見えていますが、これも次回あるいは次回以降に説明します。

[DBデザイン#11] 実例から考える: 表から実物へ

データベースの設計において、何を考えれば良いのかということを実例で紹介してきました。ここまでのところで、まずは管理したい情報を表にしてみて、その表に、必要な情報を埋め込むということを通じて、部署やあるいは業務ごとに、その対象すなわち1レコードに相当するものが違っており、それをしっかり認識する必要があることを説明しました。そこで、共通の概念があれば、別の表として切り出しても、元の表は再現できることも説明しました。ここまでは実際の表を見ながら考えれば、確かにそうであるということは理解してもらえるかと思います。問題は、綺麗に並んだ表を作れるかどうかです。これは、顧客やステークホルダーを交えて議論、調査、検討を行い、必要なデータを全部は無理としても一部でも見える形つまり表に落とし込めるかどうかというところに関わります。これは簡単なようで難しいですが、頑張るしかありません。もちろん、Excelで作ってもいいのですが、絶対にネ申エクセル化してはいけません。セル結合禁止です。そして、同じフィールドにあるべき情報か、別々のフィールドにあるべきかを常に考えつつ、1行つまりは1レコードとして合理的かを考えます。そして、よく分からないから記入しないのではなく、なんでもいいのでまずは記入するつまり見えるようにしておいて、検討を進めるということです。覚えておくのが大変なので表にしているのに、記述を躊躇しては意味はありません。

ここで、実例ではすでに4つの表が出てきました。何回か前なので、再掲ますが以下の通りです。とりあえず、部署ごとの業務を1部署に対して1つの表で表現したものの、共通概念としての「商品」を切り出したところです。

この、共通概念の切り出しというものの見方は、この会社の業務全体を俯瞰するような見地からの検討を行うことであり、いわばトップダウン的な分割ということになります。具体的なデータを表にしながらも、その表は何のためにあるのかということを理解した上で、分離可能なものを見出す手法とも言えます。実は、これはなかなか難しいことですし、これだけでは全ての表の分割は行えません。ざっくり言えば、ここまでの例では「商品」しか切り出せなかったということです。ただ、結果は得にくい方法でもある一方で、こうしたトップダウンな視点を常に持つことが重要なので、最初のフローとして紹介しました。

この後はどうするか? 次は「データそのものを見る」ということを行いますが、その時に「実物の書類を観察する」ということを行います。概念的なものの場合は実物がない場合もあり、その場合は表を作って検討するしかありません。一方、納品書のような実際に業務で使っている書類があるのなら、それを収集します。もちろん、Excelで作ったようなものもあるでしょうし、手書きのものもあるかもしれません。それら実物で、具体的なデータが入ったものをとにかく全て収集します。以下、例えば、納品書を作っているのであれば、実際に典型的なデータが入った状態の納品書を収集しましょう。どんな項目があればいいかということではなく、とにかくデータを見ます。データを見て初めてわかるようなことが結構あるのです。例えば、商品コードを書いているのか書いていないのかということも、単に項目として聞き取りをすると「商品を明細に書きます」くらいの情報しか得られません。コードの有無くらいは大したことではありませんが、個数表記に独特のルールがあって、1,000個以上の個数は特別な表記をするなど、それがシステムに入れ込む仕様かどうかはさておいて、実際の業務では複雑なルールが結構紛れているものです。なので、実物のデータをなるべく見るべきです。実物がないようなものは、表にして、ある意味で実体化することで、そこに内在するルールを見える形にします。

ということで、ここから何回かに分けて、納品書をもとに、営業部門で存在すると思われる「販売明細」という表を、データベースで実現可能な設計として求めます。結果的にいくつかの表に分解できるのですが、納品書上にあるデータが業務上の意味のある表、つまり、業務が可能なデータベースとして表現できるようにします。この後に説明するキーワードが出てしまっていますが(笑)、プレゼンの使い回しなので、お許しください。

[DBデザイン#10] 実例から考える: データベースの理論は勉強する必要があるか?

ちょっと、閑話休題的な話にしましょう。データベースの教科書では、集合論の話から入るいわば数学的な議論を土台にした解説が進められます。しかしながら、実際にデータベースを使い、設計をする上で、そのデータベースの教科書に書かれていることと、実用的なノウハウとの間に隔たりが大きいことに気付く人も多いでしょう。隔たりというか、世界が違い過ぎるというイメージを持つと思います。また、第3正規形などの考え方を学ぶのですが、それらの知識だけでは設計をこなすには遠いと思う人も多いようです。データベースの理論や数学は不要なのでしょうか? もちろん、不要とは言い切れないのですが、その辺り考えていることをまとめてみましょう。

まず、数学をベースにした理論は、初心者向けの情報ではないことは確かです。データベースの理論が数学をベースに組み立てられていることで、さまざまなことが高度に客観的に検証したり、証明したりということができるのです。つまり、数学がベースにあることで、確固した結論が得られていると考えられるというところがポイントです。よって、数学ベースの理論は無視はできないのです。厳密すぎて、最初の定義、つまり集合やドメインという話からリレーションの成り立ちまでの話はいきなり理解ができません。それはいきなりは理解できないのは当然だと思います。抽象度が高過ぎです。今時はデータベースシステムを手軽に組んで利用できる世界なので、むしろ、現実のデータをいじりながら理解し、一定のところまで理解したところで理論を勉強するというのが効率的な方法ではないかと思います。実際、私も、理論の書籍を最初に読んだ時には面食らいましたが、実際にいろんな製品を触って作ったりしている上で改めて理論の書籍を読むと、非常に頭に素直に入ってきたという経験があります。

データベースの設計におけるノウハウは、実はこうした理論に裏打ちされていると言ってもいいのですが、理論の世界で定義されていることは抽象度が高いために、打てば響く的なノウハウではないのは確かです。常に抽象度の高い世界で過ごすのは、さすがに専門家でも辛いですし、実システムは利用者あるいは発注者という存在がいるので、現実の世界に沿った説明をする必要も出てきます。その上で、いろいろな理解しやすくアレンジされたナレッジを多くの人は発案し、あるいは獲得するということをおこなってきたわけです。

そうしたナレッジが、理論の世界のどれと対応しているのかというのは、ある意味面白い話題です。表を分離するというのは第1正規形を適用しているとも言えます。しかし、直接関係してなさそうだけど、重要なナレッジもあると思うかもしれません。いずれ説明しますが、多対多の関係は中間テーブルを確保するという有名なノウハウがありますが、これは実際にそういう実装をせざるを得ないという工夫のノウハウでもあります。ただ、この手法自体は結果的に第3正規形になっているとも言えるわけで、要するに理論上での重要な結論は、必ずしも設計のナレッジのコアであるとは限らないのです。ただ、第4、第5正規形となると、これはちょっと狭い範囲の解決策ではないかとも思います。どんなデータベースでも、第5正規形の領域まで到達するということではありません。ただ、通常は第3正規形までは間違いなく到達していないと、どこかで矛盾が生じると思います。一方、マスターのデータをコピーして残しておくような処理、例えばFileMakerでのルックアップのような処理は、正規形による効率化とは逆行する面もあるものの、要求を満たすという意味で1つの選択肢になります。ただ、これも、逆に正規化が崩れている側面をどう評価するということを考えれば、やはり理論に基づいて考えを及ばせることができるとも言えるのではないでしょうか。この辺り、先々のネタで使います。

そういうわけで、私の一連のブログ記事は、プロの開発者でも、データベース設計となるとちょっと分からんという人や、あるいはそれなりに作れても自己流というか、持ち前の能力でうまくやってきたのが果たして正しい考え方なのかといった疑問を持っているような人に、設計時に何を考えればいいのかということを、理論とは異なる流れで説明をする試なのです。

ちなみに、理論や数学は学習する必要があるでしょうか? 真面目に設計をできるようになりたい方は、必ず勉強してください。よく分からなくても、ともかく頭に一度理論を流してください。忘れてもいいので、ともかく一度は勉強しましょう。そうすれば、ずっと先に、「あ、これはあのことか」というのがたまーに出てきます。それが基礎力というものではないかと思います。ただ、数学は若いうちに学習しましょう。中年以上になると、無理〜!と叫ぶことになります。私と同世代の老化著しい皆さんは、時間をかけて、そして欲張らずに勉強するしかないかと思います。

[DBデザイン#9] 実例から考える: 分離した表から元の表を得る

ここまでのところで、業務分析して、各部署で必要なデータがどんなものかを見える化するために、表を作りました。表の1行1行が表現している内容を考えれば、同じ商品という単語を使っていても、部署ごとに扱い、つまりは商品に対する概念や定義が違っていることに気づきました。また、一方、共通の概念もあり、それは商品の名前は共通であるということで、商品マスターに名前を覚えさせておこうという判断ができたわけです。

この時、商品の表を、製造管理の表の「商品名」フィールドをごっそり持ってくるということでいいのですが、同一名称の行が発生します。今のところ、商品名だけしか商品の表では登場していないので、重複したデータはなくてもいいだろうと考えます。1つだけ記憶していれば問題はないと考えます。製造管理の表では複数の同一商品が存在しますが、それぞれが同一の商品の行を参照すれば、問題はないわけです。ということで、商品の表は商品名の重複がないものにして、番号を振ったということです。

こうして分離しても、元の製造管理の表が得られます。その手続きは次の表の通りです。少ないデータだけならこうして具体的にデータを並べて考えてみるのがわかりやすいでしょう。

最初は分離した表になっていますが、左側の製造管理について、最初の1行を取り出します。すると、商品の102番を参照するようになっているので、商品の表の102番の行を照合し、そしてそれぞれ取り出します。続いて、この2つの1行を、1行にまとめます。つまり、単につなげます。この作業を、左側の製造管理の各行について行うと、最後の表になります。これは、商品の表を分離する前の製造管理の表と基本的に同じです。フィールドの順序は違いますし、商品IDも入っていますが、表として表現していることは同等であると言えるはずです。つまり、どちらの表でも、業務は同様に可能です。

このような、表から表を作る処理を「結合」と呼びます。リレーショナルデータベースの代表的な処理です。SQLでは、JOINというキーワードでステートメント内で記述します。ただ、JOINの処理にもいくつか種類がありますが、これはまた別の機会に説明しましょう。

ここで注目していただきたいのは、商品の表は重複を削除していても、問題なく元の表が再現できるということです。「ロボットいか2号」という文字列を、図で見たように、1つ目と2つ目のレコードで使いまわしています。言い換えれば共有しているのです。どちらも『行を取り出す』と記載する部分で、いわば元の行の複製を作っていて、それを結合した表に持ち込んでいます。結合した表の商品名は、全て、商品の表から複製した情報であるため、当たり前ですが、商品テーブルのデータが正確に結合した表に組み込まれていて、同一の商品の商品名は常に同一であるということです。

この結合結果は、基本的には一時的に使うのものであって、この結合した表自体を永続的に記録しているわけではありません。永続的に記録されているのは、ここでは手続きの最初の2つの表であるのが、データベースの一般的な実装になります。ただし、データ処理を高速化するために結合結果をどこかに覚えておくような最適化処理は今時のデータベースは普通になされていると言ってもよく、厳密に技術的な意味では永続化されているかもしれません。しかしながら、設計の段階では、必要に応じて結合した表を一時的に、つまり、現状の情報を一覧表を作って参照すると言ったような用途で作るという流れが一般的であると考えてください。

次回は、販売明細について検討を進めてみましょう。

[DBデザイン#8] 実例から考える: 分離した表の関係を築く

ここまでに、業務全体をみながら、同じ「商品」でも部署ごとに異なる対象として扱っていることから、記録したいデータは異なるとして、それらを表として表現しました。一方、その中でも共通の「商品」に対する情報を別の表でまとめて共有することも考えました。

この、別の表にしたもの、つまり、複数の表にしたものを1つの表として表現するということが、リレーショナルデータベースのわかりやすいメリットの1つです。なお、この1つにまとめた表は、場合によってはどこかに保存することもあるかもしれませんが、原則として一時的に利用するものであって、それを保存するデータとして利用はしません。あくまで、複数の表として保存し、必要な時にそこから元の表を一時的に得るというのが原則です。

しかし、表を分割したとしても、その2つの表の関連性はどのように確保するのでしょうか? ここで、本来はデータベースの難しい理論を勉強しなければならないのですが、1つの理解の仕方は、参照される側に「番号を降る」ということをやるのです。次の図は、「製造管理」の表に、もともと商品名があったのですが、その商品の名前は営業部門などと共有できそうなので、「商品」という表を分離しました。しかし、分離してしまったらただ消すだけです。製造管理の1行において、どの商品についての製造管理情報なのかを示すために、ここでは「商品ID」という番号を振ることにします。ここでは、「商品」側にも「商品ID」があります。商品IDは、商品が重複しない表の上で、適当な番号を頭から振っていったものです。当然ながら、商品の表の商品IDは重複がありません。言い換えれば、商品IDが決まれば、「どの商品なのか」ということが一意に決まるということです。こうすれば、製造管理の1行目は商品IDが102なので、商品の表より「ロボットいか2号」についての情報であるということがわかるのです。もちろん、ソフトウェアなのでこれをある意味機械的に行うのですが、ここでは設計に必要な概念を整理するために、まずは番号を振るということを考えます。ちなみに、番号を101から順番に振りましたが、別に1、2、3でも、10001からでも構いません。とにかく行ごとに異なる番号であればいいのです。一桁だと、個数っぽいので、わざと桁を多めにして、直感的に判断しやすいようにという意図です。

(「本セミナー」と書いてあるのは、もともとセミナー用に作った資料を流用しているからです。すみませんが無視してください。なお、いずれ、正規形についての情報は色々な形で紹介すると思います。)

ここで、製造管理は5行、商品は3行です。「ロボットいか2号」についての情報が製造管理には2つあり、つまり、2個の商品の製造をしたことがわかります。一方で、商品の表については、ここでは名前の共有だけを目指しているようなのですが、2個製造した「ロボットいか2号」は、どちらも同一の「ロボットいか2号」という商品名です。ということは、商品側では1つの存在で良いと言えます。

商品から逆に製造管理を見たとき、1つの商品「ロボットいか2号」についての情報が1行目と2行目の複数の行にあります。このような関係を「1対多」と呼ばれます。この製造管理の表はおそらく全体の表の一部なので、2個しか製造していないということはないでしょう。つまり、100個あるいは10000個と作っているような状況を想定します。具体的なデータでは何個という個数は求められますが、設計については、具体的な個数よりも「多」であって「1」や「0」といった決まった数値ではないということが重要になります。もちろん、0、1、2・・・と増えていくということで、1である瞬間はあるのかもしれませんが、「関係そのものについて、1なのか多なのか」ということを考えます。となると、商品と製造管理は、1対多であると言えるわけです。

1対多の「1」は、1行しかないということではありません。商品の1つから多数の製造管理が存在し得るということです。そして、逆に見た時には、1つの製造管理から、1つの商品が特定できるということです。このような関係を1対多と呼んでいます。逆に見た時は1対1じゃないかと思うかもしれませんが、一方が1対多なら、関係は1対多と判断します。ちなみに、「多対1」も基本的には同一概念です。説明上の順番で、「商品と製品管理は1対多」、「製品管理と商品は多対1」のような表現がされるだけで、どっちが先に書いてあるのかくらいの違いしかありません。

現実のデータベース設計ではこの「1対多」の関係を、確実に抽出しなければなりません。これに対して、前回説明した「1対1」の関係もあります。1対1の関係は、多くの場合はフィールド、つまり表の列にまとめることができます。一方、1対多の関係は、別々の表として表現するというのが確実な方法になります。本来1対多であるはずの関係を間違えて1対1であるとみなしてしまったら、単純な意味では2つ以上のデータの存在をシステム上では適切に表現できないということになります。すなわち、1対多の関係の把握が、データベース設計での肝になるということになります。

なお、以前にもよく雑誌記事などを書いたときに、リレーショナルデータベースの説明を依頼されたことがあります。そこで必ず言われるのが「番号が分かりにくい。番号が出てきたらもわからない」という編集者からの指摘です。まあ、そうですね。なんで101なのとか(前に説明した通りこれは適当な番号です)、データベースは直感的と言われるのだからもっと簡単なのじゃないかとか言われるのですが、この「番号振ります」は、単なる手続きなので、難しいことではありません。普段から番号を振って、順序を考える基準にするなどしていることと同じことなのです。ただ、普段番号を振らない、あるいは元々番号を使っていない対象に単に振っているだけです。番号振ること自体をディープに理解してほしいわけではなく、ここである意味、表に分割した結果を単純化するために番号を振るという状況を頭の中で作ってほしいというだけで、考えすぎる必要はないと思います。繰り返しますが、番号を振るのは単なる手続きです。

一方、この「ID番号」は、リレーショナルデータベースの理論の上からは必須の定義ではありません。リレーショナルデータベースは、その表の1行を特定できるデータが何かということが重視されるので、それは商品名でもいいですし、社内で使っている商品番号でもいいのです。むしろ、論理的にはその方が現実に近いということもあります。こうした表の1行を特定可能なデータを「キー」などと呼ばれます。ただ、これまでの色々な設計の経験からして、全ての表に連番を振っておくのがある意味確実だと考えます。まず、データベースは連番を振ることを自動的にできるからです。場合によってはその連番を使わないこともありますが、それによって処理が遅くなったり、ディスク容量を圧迫するようなことはないのが一般的なので、「全ての表にキーが絶対に存在する」ことを優先して、数値連番フィールドを設定します。商品名がキーでもいいじゃないかと思われるかもしれませんが、文字列は比較処理がある意味安定していません。整数やUUIDのような一定のコードは比較処理が安定しています。文字列の場合、もちろんルールを定めれば、確実に比較はできますが、Unicodeのさまざまルールや、同じ文字でもコードが違うものが大量にあるなど、文字列比較は間違える要因が多いのです。であれば、整数連番の確実性を取りたいと考えるわけです。付けられた連番がデータと無関係にランダムになるのを嫌う場合もありますが、このキーになるデータは「利用者に見せない」のが基本です。仮に見せたとしても絶対に編集可能にしてはいけません。最近は多くの開発にフレームワークを使うこともあるので、自動的に数値連番をつけることもありますし、単一の数値での処理が組み込まれていることもあるので、結果的に数値連番フィールドを使うことになるのではないでしょうか。

次回は、この分離した表から元の表が求められるということを、細かい流れになりますが、説明しましょう。

[DBデザイン#7] 実例から考える: 共通の概念を抽出する

前回の再掲になりますが、ここまでに、部署ごとに、その部署での関心ごとについて表にしていきました。ここで、フィールド名をつけるところまでを解説しました。

続いて、この一連の表から、共通の概念を持つデータを抽出します。厳密には、正規化の議論があって、そのルールに基づくという手法もあるのですが、ここでは会社のドメイン、部署のドメインについて、要求分析を通じてだいぶんと理解が深まったという状況をもとに考えてみましょう。

まず、ここでどの表にも「商品名」があります。であれば、商品名を共通化することで何かメリットは生まれないかと言うことを考えます。それぞれの表にも名前をつけることにしますが、加えて、商品名だけを独立させた「商品」と言う表も記述してみました。つまり、「販売明細」「製造管理」「カタログ在庫」いずれも、「商品」にある商品名の文字列を持ってきて表が作れるというものです。こうすれば、販売管理や製造管理において、何度も繰り返し登場する1つの商品名を記述することなく、商品名はシステムの中では商品の中に1箇所登場するだけにすることもできそうです。効率が良くなるかもしれません。

ちなみに、これが「商品マスター」と呼ばれる考え方の1つの理解の仕方です。効率良いことと、修正の確実性ということが言われます。例えば、商品名を間違って記録していたら、それが最初の図のような表の場合、表の中で一括置換をするなど、変更が重い処理になり、また確実に終わりそうにない処理にもなります。マスターで一元的に商品名を管理すると、商品名が違っていても、1箇所直すだけです。しかしながら、商品名の間違いってそんな頻繁にはないでしょうという気もするかもしれません。実際そうですが、実はマスターの役割は確実に変更できるということ以外にさまざまなことがあります。システム内では、データの複製をするような場合が出てきます。要求から、ここのフィールドは複製が必要と判断される箇所は時々出てきます。その場合でも、マスターの内容を複製することで、確実に名前を入力できると言ったこともあります。この辺りは、リレーショナルデータベースの理屈だけでは説明しきれない側面です。ただ、実際にある製造管理によって管理されている個体の商品が、商品テーブルをどのように参照するのかということは、実装上のルールがあって、それは次回に説明したいと思います。

「商品」という存在は、部署によって共通であり、商品名は、どの部署でも同様に利用できるという、ここでは表にまたがって存在するデータの共通性を見つけました。実際には、さらに販売先顧客名が重複しているなどの問題はありますが、それは追々見つけましょう。

ここで、概念が共通という意味では、日付もそうではないかと思いませんか? もちろん、販売日と製造日は、対象が異なりますが、いずれも、日付という共通の概念ではないかと思うところです。たまたま、この表では同じ日がなかったということです。では、日付を共通化するのかというと、おそらく多くのデータベースでは共通化していないと思われます。これはなぜなのでしょうか? 日付や時刻はいずれも3つの整数を持つような複合データであり、突き詰めて考えれば複雑そうです。この結論を先に言えば、日付や日付時刻といったデータは、データベースが持つ型として定義されているからです。言い訳っぽい理由になりますが、「商品」という型はありませんが、DATEやTIMESTAMPといった型があり、日付という単独の値、つまり、数値などと同じように扱えるから、多くの場合は別の表に分離しないということです。仮に別の表に分離しても、1フィールドだけです。商品の場合は、ここでは明示していませんが、おそらく商品名だけでなく、販売開始日など、共通の概念として「商品」に紐づく属性がフィールドとして付加されることになるでしょう。つまり、この会社における共通概念の商品を扱うために必要な情報を追加することになります。しかしながら、日付は多分日付だけなのだろうと思われます。

しかし、日付を別の表に分離しないと対処しづらい場合もあります。それは日付以外の情報が入っている場合で、例えば、祝日の管理が挙げられます。また、その会社特有の記念日(創立記念日など)もあります。そうなると、日付にもう少し意味が付加されてしまい、実はそれは「予定表」だったりして、「日付」という概念ではなくなってくるでしょう。予定表の日付ということで、ここでも日付という型があることで、単独フィールドとして扱えるというあたりが日付時刻についての特殊性とも言えます。

このように、とにかく「マスターを作る」というデータは1つの案件内では結構あり、いくらか経験を積めば、大体いい感じに設計できると思います。しかしながら、そこには、表ごとに異なる「商品」と、表を通じて共通の「商品」の概念があって、後者がマスターになるということを理解しておく必要があります。ところで、共通というのは実は抽出時に考えることで、運用上はそこまで厳しくありません。商品の販売単価は、おそらくはここでは営業部門だけが使いたいでしょう。では、それは商品マスターに入れるのかというと、実は入れることが一般的です。これは、他の部門では無視すればいいというのがまずはざっくりとした見方なのですが、より重要な概念があります。単価は、その共通概念である商品1つについて、1つの値が割り当てられる属性であるとみなすことができれば、それは商品マスターのフィールドの一つにすればいいのです。そして、必要な表では使い、不要な表では無視するというのがデータベース利用のポイントになります。ここで、「商品1つについて1つの属性」、つまり、1対1の関係であることをしっかりと考え、確認しておく必要があります。実は、部門午後の表のフィールドは、その表1行の概念に対して、1対1の関係が成り立っているものが並んでいます。作ってある表はちょっと恣意的ではありますが、こうすれば、整理されているとも言えるでしょう。

次回は、分離した表から必要な情報を持ってくるというリレーショナルデータベースの基本的な考え方を説明しましょう。

[DBデザイン#6] 実例から考える: 表で考える

前回までに、単純な「商品」という単語でも、状況によって異なるものを示すことを説明しました。実際の開発では、これと同じように、たくさんのユビキタス言語を認識して、それらを分析し、必要な仕組みを考えていくことになります。その時に有用な考え方が、まさに「表」です。それぞれの部署で記録したいデータを実際に表に作ってみます。場合によってはすでにその部署で表が作られている可能性もあります。しかしながら、もっと大雑把なデータしか得られないかもしれません。これは利用者側作るものではあるのですが、表の内容が無茶苦茶でないかなどはやはりエンジニアリング的な視点でチェックしないといけません。表の内容が途中から変わってしまっているような表の利用は要注意です。

それで、ここでの実例でできたおもちゃロボットメーカーについて、ちょっと恣意的ですが、システム化したい業務についての根幹となるデータを表にしてみます。現実にはこんなに単純明快ではないとは思いますが、考え方のサンプルということです。

現状、多くの仕事はExcelが絡んでくるので、中途半端にシステム化されていることが多いでしょう。特にExcel自体を「便利に使っている」ような職場では、システム化と言っても、ヘタをするとExcelの再発明を求められてしまうことも、結構あります。表にするのですが、ここで何を求めたいかのかというと、1レコードに相当するものとして何を見るのかということです。実は営業部門が一番わかりにくいです。営業については実際にはリレーショナルデータベースの典型的な例でもあるので、少し先に詳しく説明しますが、あえて「営業は、紙の納品書を作っている」くらいの感じで考えていただければ、いつ、どの顧客に、どの商品をいくつ売ったのかという情報を記録することで、月末にまとめて請求ということができるかと考えます。ここでの表は、納品書の明細が1レコードになりそうです。言い換えれば、それより小さな単位がなさそうであるというくらいの根拠です。商品や顧客は当然ながら表には繰り返し登場します。

製造部門はある意味わかりやすいです。作った箱入り製品1つずつを管理したいのですから、1レコードは、1ボックスということになります。マーケティング部門は、とりあえず製品カタログの残り部数を管理するとしたら、1レコードは、まさにマーケティング部門が把握する1商品ということになります。

なお、このままだと、データベースの設計に持ち込めません、ここからまだやるべきことはあるのですが、重要なことは、実際に現場で発生しているデータを記述するということです。ここで、単に曖昧に記述するのではなく、表の形で頑張って記述するということです。全部でなくても構いませんが、少なくとも、表の数行分を記述してみることが必要と考えます。もっとも、そういう表の形になったものを頭の中で再現して、何も書かずにできる人もいます。設計が得意な方はそれができるかもしれません。しかしながら、こうして作り込んで行くコアな考え方が正しいかどうかを検証するのは設計が不得意な人かもしれません。記述して見える化するという意味では、表は出発点としてはみんなが理解できるものとも言えるもので、大変有益でしょう。

ちなみに、ここではそれなりに整理してしまっている感じですが、空白があるのは当然としても、同じ列に途中からデータの種類が変わってしまうこともあります。その場合は列を分けるなどします。つまり、列で分類するという言い方もできるでしょう。そうしているうちに、列に名称をつけることができるようになります。その列にあるデータの代表的な名前をつければ、逆にその列に何のデータが入れられるのかも理解しやすくなります。もちろん、それがすでに紹介したフィールド名になります。

フィールド名の命名ルールは結構人それぞれですが、少なくとも、「代表名」であるというのはほぼ全ての方に同意いただけるでしょう。また、データベース上では同一のフィールド名を複数つけることは許されていませんので、異なるフィールド名にしなければなりません。また、長すぎると式を書いたりするような時に結構面倒です。ということで色々悩みます。以前に大変分析が困難なデータベースにあたったのですが、どう困難かというと色々あるのですけど、「適用_編集用」と「適用編集用」みたいなフィールドがあって、フィールド名で判断が極めて困難という状況でした。このようなフィールド名だと、「フィールド1」「フィールド2」と付けられているのとあまり変わりません。さらにその時にはオチがあって、それらのフィールドの前者はPDF出力時、後者は印刷時に使われるというこれまたクイズのような(パズルではなく!)データベースでした。

いずれにしても、フィールド名はよく考えて、統一的な名前で、かつそこに入ってくるデータが連想しやすいものにするのが言うまでもありません。例えば、「平均値」と言う名前のフィールドをつけたけど、そこには月間の平均値が入っているとします。しかし、やっぱり週の平均値も欲しいので「平均値_週間」フィールドを作ったとします。そうなると、「平均値」ではなく、「平均値_月間」フィールドにするのがベターな方法ではあるのですが、そこをそのままにするエンジニアが多く、後からデータベースに関わる人たちに混乱をもたらしてくれます。もちろん、プログラム内にフィールド名が文字列で記述するような場合、下手にフィールド名は変えたくないと思うかもしれませんが、一括置換すればいいことです。また、FileMakerでは基本的に気軽にフィールド名は後から変えられます。今、この平均値が売上だったとして、個数の平均値が欲しいとなると、どうしましょう。この集計した結果のフィールドは「売上_平均_月間」のように、処理対象、処理方法、グループ化基準といった情報が、どのフィールドにも、同一のルールで、同一の用語で入っていないと、分析が辛くなります。日本語の用語だと思っていたら、途中から突然英語になってしかもカタカナだと(「売上_アベレージ_年間」みたいな)何かのギャグか嫌がらせかと思ってしまします。用語のルールも重要ですが、自分で決めたルールを全体にわたって最後まで踏襲するということがもっと重要なことになります。

ところで、フィールド名自体に「データ」的な性質の文字列が入るのは、ちょっと違和感あるものの、ある意味便利なのかもしれません。例えば、アマゾンから購入したかどうかを記録する「Amazon購入」フィールドはどうでしょう? では楽天やモノタロウと購入先を増えてきた時にそれぞれ別々に管理したければ、フィールドを増やすしかありません。通常、そうなると、「購入先」と言うフィールドに文字や数字で区別して購入先を記録するのが妥当な気がします。となると、フィールド名は抽象度の上がった名称であるとも言えて、実はフィールド名にデータ(この場合は「Amazon」と言う文字列がある意味ではデータです)が入ることはないと言うことも言えます。しかし、単にAmazonだけ特別で管理したい場合には、「Amazon購入」フィールドは、わかりやすいので悪くはないと思います。この問題は、結果的に最後まで作ってみないと正しかったのか、正しくなかったのかはわからないものの、ルール的には一概に決められないと言うことでもあります。

そういえば、フィールド名に表の名前を入れるかどうか問題もあります。これに関しては入れないのが基本だと思います。入れるとしたら、全部のフィールドに入れないと妙にも思えるからで、それは非効率的です。ところが、「名前」と言うフィールド名は、それだけ単独あってもわかりづらいです。そのような場合は「商品_名前」にするという手もありますが、SQLの世界では「テーブル名.フィールド名」の記述が随所にできるので、表の名前はフィールドになくても、表現は可能とも言えます。ですが、極めて一般的な名称については、やっぱり表の名前をつけたり、あるいはそれを連想させる名前をつけたくなってしまいたくなります。これは感覚的な問題です。加えて、あちこちのテーブルに「名前」フィールドがあるのも、混乱の元かもしれません。

ついでに、フィールド名に誤変換や間違えたスペルはなるべくやめましょう。データベースを分析しているときにストレスが強くかかります。見る度に、何だか設計・分析とは違うスイッチが入るのですよ。スペルは今時の開発ツールではみてくれますが、誤変換は自分で見つけるしかありません。データベース全体に渡って「精算」であるはずが「清算」だったものを見たことがあります。レイアウト上は流石に利用者が指摘したのか「精算」になっているのですが、フィールド名が全部「清算」でした。

次回は、この表にした結果をもう少し分析してみましょう。

[DBデザイン#5] 実例から考える: “商品”に注目する

前の記事では前提となる会社の業務を紹介しましたが、どの部署にも「商品」という単語が出てきました。データベースに慣れているみなさんは「はいはい、『商品マスター』でしょ」と思われるところかもしれません。もちろん、商品マスターは作るのですが、なぜ商品マスターが必要なのでしょうか、そして、それだけでいいのでしょうか?ここで、「商品」というキーワードをより詳細に分析してみます。

次の図では、それぞれの部門に対して、「商品とはなんでしょうか?」と質問した結果だと考えてください。実際、要求分析をするときに、そんなダイレクトな質問はいろんな意味で(機会やあるいは適切な担当者と話ができるのかなどを含めて)無理でしょうし、しかもちゃんと答えてくれるとも限りません。通常は、いろんなインタビューをもとに、分析者がこうではないだろうかと考えるのが一般的かと思います。なお、前回は経営者が出てきましたが、言っていることが曖昧なので、ここから先は3部門だけに絞りましょう。

営業部門にとって、商品は売っているものです。製造部門は作っているものです。この辺りは明確でしょうけど、どうもマーケティング部門にとっては、商品というのは何なのかということがどうも曖昧で、具体的に言いづらい感じです。おそらく、状況によって変わるのでしょう。

ここで、部署ごとに、商品をどのように扱っているのかをみてみましょう。それを示したのが次の図です。

まず、製造部門は、製造した商品1つ1つをどうやら管理したいようです。つまり、商品の箱1つ1つが対象になります。一方、営業部門は、商品の箱があることは理解しているでしょうけど、商品そのものを集合的に扱います。しかも、製造部門は、商品の物理的なことを考えなければなりませんので、在庫ということまでもしかして考えているかもしれませんが、営業部門はおそらく商品という存在を移動させているという考えが支配的ではないでしょうか。つまり、営業担当者は、実際に自分で箱を手に取って顧客に届けているというよりも、伝票を書いて、ロジスティックスに依頼をするわけで、実際に商品そのものを目に見ていることは滅多にないようなのがいわゆる営業という活動ではないかと思われます。マーケティングに至ってはなんだかわかりませんが、インタビューでどうやら商品カタログの管理くらいは必要なことがわかったという程度です。

同じ商品という呼び方をしているのに、このように部署によって実は扱う概念が大きく変わってきます。当然、それらを一緒くたにするのは問題があると考えます。部署ごとに違いがある一方、共通の概念もあります。例えば、商品名は社内で統一的に扱われているはずです。一方、商品の単価が業務上必要でしょうか? 販売部門は伝票を作成するのに必要そうです。一方、製造部門は単価が存在しても、業務上は通常は使わないでしょう。一方、マーケティングはおそらく単価情報は、業績等をチェックするような場合に使うかもしれません。商品1つずつにつけるシリアル番号はどうでしょう? 製造部門には必須かもしれませんが、営業部門には興味のないデータです。このように、共通のものと共通でないものが存在するのです。

ドメイン駆動開発の世界では、こうした概念を「ユビキタス言語」として捉えます。ある特定のコミュニティで通用する言語なのですが、つまり、ここでは「営業部門言語の商品」と「製造部門言語の商品」に若干の違いがあると考えて、これらの部門間では異なるユビキタス言語が使われていると考えます。同じ言葉で違う概念があるということは、ドメインつまり「業務そのものの定義」が異なるという考え方です。実は、商品というよく似た言葉でも、このような違いがあるものの、社内で働いていると、なんとなくそういうものだということでドメインが違うことは気づきにくいものです。まさに、第三者が設計するときに、そうしたドメインの違いを見出すことができ、業務の整理が進むということが期待できます。もちろん、分析者や開発者は、顧客のドメインを理解し、ユビキタス言語を使いこなせるくらいになっていることが理想です。

ユビキタス言語は、そのドメインのモデルの基礎になるものです。言語を構成する概念を整理したものがモデルとして利用できるでしょう。ユビキタス言語はモデルが表面に出てきたものでもあります。私たちは、ドメインのモデルを知りたいのです。そのモデルをデータベースに実装すれば、システムは成功するはずです。モデルを探るのが要求分析であり設計です。その手がかりがユビキタス言語にもあるということです。

ちなみに、1つの言葉が異なる概念を示すだけでなく、異なる言葉が同じものを指す場合もありますし、1つの単語が状況によって異なるものを示す場合もあります。最後の例は1つの単語が同一職場の同一業務で状況によって違っていたのですが、よくそれでトラブル発生しないもんだと思ってしまいます。たまたま問題にならなかったのでしょう。言葉というのはコンテキストを引き連れて登場するので、区別は可能なのかもしれませんが、外部からその世界に入ってきた人には面食らってしまう事象です。こういう事例があった場合は、ドメインをまたがって用語の整理をするのが理想なのですが、なかなか業務の上で使い続けている言葉は変えてもらえないのが実情です。

ドメイン駆動開発といえば、現在はマイクロサービシズで話題になっていますが、ドメイン駆動開発の方が先に提唱されていた概念です。マイクロサービシズでは、どんなサービスに分割をするのかというのが設計上の大きな問題です。ここでサービスの分割を考えるとき、ユビキタス言語の通用する範囲を重視するという考え方があります。これを、非常に雑に考えると、要するに部署ごとに別システムであり、部署間の動きが必要ならそれはシステム連携だろう、そしてシステムは1つのマイクロサービスであるとも言えるとも言えます。実は、マイクロサービスシズの勉強を一時期頑張っていた時期があり、いろんな資料に当たったのですが、あっさりと「マイクロサービシズは、部署ごとに分ます、以上」と説明されているものがありました。その資料ではドメイン駆動開発やユビキタス言語といった抽象概念はすっ飛ばしていました。あらあらと思いつつ、非常に大まかに言えばそういうことで、間違いはないかもしれませんが、会社の部門構成が最適化されていないと色々苦しいだろうなと思ったりもします。しかし、最適化されていない会社ってきっと破綻するでしょうから、システム作っても早晩使われなくなる? ということで、部署でサービス分けるというのはあながち悪いサジェスチョンではないと思った次第です。そこで、ここでの実例も、部署を単位にしてみました。

商品のような基本的な単語でも、そのドメインによって役割が違うようです。実際、みなさんの会社やあるいは扱った案件ではどうでしょう? 他には「在庫」なんてどうでしょう。在庫と言ってもいろんな概念があります。会計的には在庫は金額ですが、倉庫で働く人にとってはそこにあるたくさんの段ボールだったりします。商品や在庫などはどの会社でもあるようなものなので、ある意味では扱い方はある程度はわかっているようなものでもあり、経験則も適用できるかもしれませんが、むしろ、わかったつもりになるのは危険で、そのドメイン特有のルールや扱い方がないかを常にアンテナを張るくらいの気持ちがないと、後から気づいて大きく出戻りが発生するということにもなりかねません。商品や在庫だけでなく、部署ごとに違う、あるいは担当者ごとに違うような概念がないかを見つけてみるのも良いでしょう。また、部署で違うだけでなく、部署を横断するようなドメインの存在も見えてくるかもしれません。要求分析以降は常にドメインやそこでのモデルを意識する必要があります。

次回は、異なる概念を表を作って捉えるということを説明しましょう。

[DBデザイン#4] 実例から考える: 前提となる業務

今回から、数回に分けて、データベース設計をするときにどこに注目するのかを考えることにします。一応、「分かりやすい」業務を架空の会社でおこなっているという想定です。もっとも、そういう架空の設定そのものが、いかにも記事をそれらしく見せるためのわざとらしい前提に見えるかもしれませんが、やはり現実の世界そのままはなかなか複雑で理解しづらいですし、現実には「要求が不明あるいは曖昧である」という問題との対峙が非常に難しいところになります。なので、問題を単純化したいと思います。

データベース設計の1つの肝は、「1レコードに相当する単位あるいは概念の特定」だと考えます。そのために、どんなフィールドが必要かを集めて分類などを行うと思いますが、1レコードの特定が設計の1つの目標になります。そこに至るまでに、表にして考えるということをまずはこの実例で見ていっていただきたいのですが、表が出てくるのは次回以降になります。まずは、ロボット製造販売を行うような会社がありますという前提の説明をしましょう。あえて非現実的にするために、おもちゃロボットがなぜかヒットしたという会社を考えます。画像素材は誰が見てもご存知のイラストやさんです。ありがとうございます。

まず、この会社には営業部門があります。製造したロボットを、卸売や大手小売業者に販売します。営業部門では、「ロボットさんま1号 x 24個」のように、この会社の商品を、通常は複数個まとめて出荷するという作業を行います。営業部門が考える関心ごととは、ともかくたくさん販売して、売上を伸ばすことです。また、季節性のある商品や何かイベントなどでの売上の波が来そうな場合に、別の部門との折衝を行なって在庫確保などもしているかもしれません。

一方、この会社には製造部門も持っています。製造はどうやら外注していないようです。製造部門は、当然ながら、商品を1つずつ作ります。まとめてどこかに在庫しますが、どうやら出荷計画を作ってそれに基づいて製造をするという大きな流れを持っているようです。この部門の関心事は不良品がないなどの製品品質を高めることが大きいようです。

さらにマーケティング部門もあります。マーケティング部門なので、現状の商品を訴求するためのさまざまな活動が行われていますが、一番大きなミッションは新たな市場を作るということを経営側から命じられています。この部門にとっては、商品1つ1つは関心ごとではなく、商品という大きな概念そのものを扱っていると言えるでしょう。

もちろん、この会社には経営陣がいます。もちろん、経営陣は会社の収益を確保し高めることが一番の関心事になりますが、どうやらこの会社はハイテクな商品を作っているように見えて、情報システムは部門ごとに作ってしまっているようで、連携はしていないようです。

このような会社で、部門にまたがって使える業務システムを設計するということが発生しました。ということで、設計を進める上で何を考えるかということを考えてみたいと思います。これくらいの内容なら、すぐに作れるよとおっしゃる方もいらっしゃるでしょうけど、そういう方が頭に即思い付くような「テーブル構成」がどのように導き出されるのかを、「表を作ってみる」というアクションから考えてみたいと思います。

[DBデザイン#3] 表のモデル

昨日このポストを書いた後、サーバーのメンテを長くやってないなと思ってアップデートをかけたら、一気に起動しなくなってしまってデータが消えてしまいました。ある程度はバックアップしてあるので、メッセージは一昨日分まで、画像などは2019年までしかなかったです。まあ、でも、Ubuntu Server 20.04に入れ替えて心機一転です。ただ、同じ内容を書いても、日が変わると内容が違って来そうで、いいのか悪いのか、ともかく昨日書いた内容を思い出しつつ、変化しながら書きます。

データベースの設計を行う上で、まず、データをどのように見るのかという基本的なことで、表を出しました。表に対して、レコードやフィールドといった名称を定義しました。多くの方が表計算ソフトを使っているので、表は便利かつ有用であるというのは理解はしていると思いますが、それが「なぜ?」を突き詰めると実はなかなか難しいということも説明しました。ほとんどの方が、表にまとめて、あるいは表にまとまったものを参照して、何か目的を達したり、より効果的に作業ができるなどの成功体験があるということがあるでしょう。そうした体験から有用性を理解しているということが、ともかくの理由でした。

なお、数学的な世界では、集合の仕組みを利用して、表そのものをきちんと定義するということは可能であり、いわゆるデータベースの教科書ではそうした集合論をベースにした表の定義が最初の方で説明されています。いきなりその辺りで挫折する方も多いかもしれません。また、そうした高度に抽象化された世界が実際のデータベース設計にどこまで役に立つのと問われると、最初のとっかかりとしてはやはりきついと思います。データベースの設計をある程度理解した時、そうか、基本は集合だったよなということを思い出すことで理解が深まるということもあります。

いずれにしても、まずはデータを表として記述することで、ある程度コンパクトに、そして存在するデータを余すことなく記述できます。つまり、Excelでなんでもできるでしょうというあたりの考えに近いかもしれません。つまり、表はそれで完結した世界です。しかしながら、私たちは書ききれないほどの大量のデータを扱いたいのでデータベースを使おうということがあります。この時、データベースは表形式にデータを扱いものの表の縦横を自由に使うのではなく、まずは行に相当するレコードに区切り、レコードはフィールドとして分割され、フィールドにデータを入力できるということを説明しました。その状況をツリーのように記述できます。ここでの線は、導出可能であるということを意味しています。つまり、あるレコードが決まれば、そのレコードからフィールドの値が取り出せるということです。プログラミング言語で処理をすると、実際にそうした側面が強く出ますが、ここではモデルの段階から表はレコードの集まり、レコードはフィールドの集まりであるということを意識したいと思います。

このように、表は階層的なツリー図で表現できるということであれば、表とツリーは同一のデータを示していると言えます。ただ、ツリーの方が実際に描画するのは大変そうですが、概念としては同一のものを示しています。

ここで、具体的にデータが存在するのはフィールドです。レコードもデータの集まりではあり、要するにフィールドの集合ではありますが、単一のデータを持つわけではありません。その意味では、レコード、そして表自体も存在がちょっと抽象的になります。それをまずはあえて楕円形のオブジェクトで書きます。レコードには名前等がないので、便宜的にレコード1などと数字付きで書きますが、表そのものには「住所録」といった名前があります。

ここで、表自体の設計情報を記述する場合、もちろん、全データを書くというのは設計図としては複雑すぎて意味がありません。設計、つまりモデルは、興味のある対象に絞った情報を集めたものというのが原則です。それを、必要な情報に捨象するといった言い方をします。つまり、「どんな表なのか」ということを如実に示す情報が欲しいわけです。

ここでの表を見てみると、まず、どのレコードも同じフィールドを持っています。そのフィールドの実データではなく、フィールドの名前を使って、どんなフィールドが存在するのかを記述してみると、次の図のようになります。どのレコードからも、同一のフィールドが存在するので、全レコードについて記述する必要はなく、レコードは1つだけで良いでしょう。

ここでさらに、表はレコードの集合であるということが決められているということでああるのなら、レコードが存在しますということをモデル上に表現する必要はないとも言えます。ただ、「しない」わけではなく、そういう表現をすることもありますが、ここではシンプルな表はみんな同じ考えで見ているとして、レコードの存在はあえて書かなくても同じフィールドを持つものが複数存在するということを前提とします。すると、残ったものは、表の名前と、フィールド名です。これらを、ちょっとわざとらしく、ボックスに書いてみると次のようになります。

これは、ER図のエンティティのようでもあり、クラス図のクラスのようでもあります。いずれにしても、こうした記述が住所録を管理する表の設計として認識できます。元は表ですが、それを階層的に見た上で、必要な情報だけを残すと、このようなものができます。データベースの設計者は、このボックスを見ることで、実データが表として展開されて、たくさんのデータが入るという状況を想定し、それが実際のシステムの用途に合致したものかどうかを検討しながら設計を進めるということができるのです。

ここで、命名が「住所録」といった集合的なものになっている点にちょっと気に掛かる人もいるかもしれません。ここはある意味好みの問題なのかもしれませんが、表に対して名前をつけているのか、レコード1つに対する名前なのかで分かれるところだと思います。データベースの設計では、レコードとして実現されるので、表とレコードは最初から組み合わされているので、ER図のような世界に入り込めるのです。これがクラス図であれば、「住所録」ではなく、「顧客」などの単一レコードを示す名称をつけ、さらに「顧客リスト」といったクラスを考えて、顧客リストは顧客の集合、つまり表とレコードの関係のような記述をする方が落ち着くと思われかもしれません。クラス図の方が抽象度が高いので、いろいろな記述のバリエーションは考えられます。これは、結果的には設計者がどう決めるかの問題です。少なくとも、1つの設計の中で、ボックスの粒度をどう扱うかを統一した上で、そのルールが他の人にわかるようなコミュニュケーションをしているかどうかということです。

私自身は、クラス図で書くことが多いのですが、いきなりデータベース設計するのではなく、まずはドメイン分析からスタートして詳細化してデータベース設計に持ち込むので、その結果クラス図で記述する異なってしまいます。もっとも、使っているツールのastah* professionalは、クラス図からER図を作成できるので、単にツールで書き換えればER図になります。また、クラス図で記述すれば、オブジェクト図を書くことができます。オブジェクト図はクラスに基づくオブジェクトであり、つまり実データが入ったボックスを記述できます。その仕組みにより実際のデータを当てはめてみて、それが意図した状態を表現できているかということを、検証することが可能です。複雑なデータであれば、そうした設計から実データ展開した検証をしたくなりますが、クラス図とオブジェクト図で、作業が可能です。クラス図でスタートしたら、結果的にクラス図で記述したデータベース設計になり、自分としては違和感ないのですが、怪訝な顔をされることもありますね。

次回からは、架空の会社の業務を想定した上で、同じ名前の対象物に対して、部署ごとに管理したい内容が違い、結果的に違う表が必要になるというお話を何回かに分けて行います。