テーブル設計 データモデリングのエッセンス (3)

ビジネスイベント系テーブルの初期モデル

UMLのアクティビティ図とか業務フロー図で、業務のステップを洗い出す。
受注→出荷→請求→回収(入金)
一つ一つのステップが、ビジネスイベントそのもだから、それぞれ、テーブルにして記録すればよい。

私の場合は、ER図でビジネスイベントの発生順に左から右にイベント系のテーブルを並べる。つまり、ER図がビジネスプロセス図にもなっている。



主キーと外部キー

主キーは、受注番号などの自然キーではなく、システムで生成するサロゲートキー(代替キー)を使う。前回説明したように、受注変更の場合は、同じ受注番号で、別のレコードを作成するので、受注番号は、主キーにできない(しない)。

外部キーは、先行するイベントの主キーを参照する。

後続するイベントへの外部キーは先行イベント側に作成しないこと。ビジネスイベントの発生時点では、後続イベントの情報は存在しない。発生時点で存在しない情報は、記録できない。するべきではない。

イベントの発生順で外部キーを実装して、参照制約を宣言しておく。

ビジネスイベント系テーブルは What Who When

ビジネスイベントの記録は、What Who When が基本3点セット。

受注レコードの例:

What : 何を受注したか
Who1 : 誰から受注したか
Who2 : 誰が受注したか
Who3 : 誰が記録したか
When1: いつ受注したか
when2: いつ記録したか

3点セットといいながら、実は、6点セット。
ビジネスの記録は、行為者(誰が受注したか)と記録者(レコード作成者)は、別に管理したほうが実践的です。

When も、ビジネス上の受注日と、レコードを作成した日時は別に持つほうが良い。
ビジネスイベントが実際に発生した日時とデータベースに記録した日時は、通常は一致しません。

備考欄は別テーブル

ビジネスイベントの記録に備考欄や摘要欄を設けて、テキストを入力可能にすることも多い。
このテキスト情報は、別テーブルにして、受注レコードへの外部キーを持つべきです。イベントテーブルは、あくまでも、必ず記録できる、NOT NULL 制約のカラムだけで構成する。

イベントテーブルと備考欄テーブルに分けるのも、役割を単純化したテーブルを作る、というテーブル設計の原則の適用例です。関心の分離です。

イベントの基本情報だけで十分な業務と、備考欄にも関心がある業務は通常は別です。備考欄の内容によって発生する業務は、例外系の業務になることが多い。この例外系の業務用にシステム機能を設計・開発するときに、関心を分離したテーブルになっていることのメリットがでてきます。

Core Domain or Generic Subdomains ?

ビジネスイベントのテーブルは、Domain-Driven Design の Responsibility Layers の Operation Layer の永続化の実装パターンです。

Operation Layer (業務の層)であるビジネスイベントのモデリングやテーブル設計は、ビジネスアプリケーションの基本部分です。業務システムであれば、必ず、なんらかの実装が必要です。

この領域を「基幹システム」と呼ぶことがある。ただし、この部分は、業務システムにとって、必須ですが、中核( Core Domain ) とは限りません。そのビジネスにとって、競合との差別化のポイントや競争力の源泉こそが Core Domain としてモデリングと設計の重点になります。

私は、ビジネスイベント系のモデリングとテーブル実装は、ほとんど場合、Generic Subdomains だと思います。つまり、世の中に良いものがあれば、それを流用して活用する。最も優秀な人材は、この領域ではなく、もっと本質的な課題を担当させるべきでしょう。

既存のモノを利用する場合、パッケージソフトという選択肢があります。私は、それよりも、書籍で公開されている、汎用モデルを流用することが多い。
データモデルリソースブック
データモデルパターンズ
アナリシスパターン


パッケージソフトにせよ、公開モデルの流用にせよ、それを評価して、採用方針を決めるのは、もちろん、経験豊富で優秀な技術者が判断する。ただし、具体的な設計や実装は、そこそこの技術者にまかせる。あまり凝った設計をやりすぎないようにリードしてやる。

イレギュラーな処理のモデリング

ビジネスイベント系のモデリングをするために、現場でヒアリングをすると、さまざまなイレギュラーな処理や「特別の」やり方がいろいろでてくる。

そして、その「特別な処理」こそ、差別化の要因、競争優位の源泉と考えている人も多い。

ここの見極め、利害関係者での方針の共有は、重要な問題です。

私は、たいていの場合は「特別の処理」は、業務のムリ・ムラ・ムダであり、もっとシンプルにすることが、ビジネスの成功要因だと思います。そこを整理して、エネルギーをもっとほかの場所に向けることが成功要因になる。

ただ、競合との差別化を徹底した「特別の処理」で実現する、という道もあると思います。その方針が経営ビジョンから、日々のオペレーションレベルまで一貫して実施されるなら、すばらしい戦略になる可能性がある。

前者であれば、ビジネスイベント系のモデリングは、Generic Subdomains であり、既存のモデルやパッケージの活用を重視する。

後者であれば、Core Domain であり、優秀なメンバーを投入して「特別な処理」を効果的に進めることができる、オペレーションのモデリングを行い、システムの設計と実装を行う。

典型的なアンチパターンは、方針は、前者なのに、モデリングと設計は、後者、というパターンです。

Core Domain でない領域に、優秀な人材を投入して、時間とエネルギーを浪費する。


テーブル設計 データモデリングのエッセンス(2)

テーブルのタイプ

データベースに記録する情報の性格から、テーブルを三つのタイプに分類する。
・ビジネスイベント:受注、出荷
・ビジネスリソース:商品、顧客、店舗
・ビジネスルール:価格表、手数料、

これは、Eric Evans の Domain-Driven Design (DDD) の Responsibility Layers の考え方と同じです。

今回は、ビジネスイベント系のテーブルの設計原則をとりあげる。

ビジネスイベントの記録

受注や出荷は、ビジネスイベントが発生した時点の記録です。このタイプのテーブル(情報)は、過去の事実の記録ですから、一度作成(インサート)したら、後から、更新や削除はしない。このテーブルに許される操作は、インサートと参照のみにする。

受注取消は、受注取消テーブルに記録する。受注テーブルに論理削除フラグを作って更新したり、受注テーブルの物理削除はしない。過去の記録は書き換えない。

受注変更は、受注取消テーブルに取消を記録し、受注テーブルに受注レコードを新規に作成する。受注レコードは更新しない。レコードの削除もしない。有効な受注は( 受注 MINUS 受注取消 )で導出する。

出荷は、出荷テーブルに記録する。受注テーブルに出荷フラグや出荷日付カラムは作らない。

ビジネスイベント系のテーブルの設計原則

受注は受注、出荷は出荷、受注取消は受注取消のそれぞれの用途別にテーブルを作成する。
「テーブルの役割・用途は一つ」の設計原則です。

発生した事実の記録は発生時点での作成(インサート)だけにする。後から、更新したり、削除したりない。

取消は、取消イベントとして記録する。
変更は、取消+追加で記録する。

予定も過去の記録である

予定日など未来に関する情報も「予定した」という過去の事実として記録する。
予定変更になった場合も、予定取消を記録し、変更後の予定を新規にインサートする。

受注残の管理

( 受注 MINUS 受注取消 ) MINUS 出荷 

過去の事実の記録から、受注残を論理的に導出する。

業務量が多いと、このやり方は性能面で問題が起きる。解法の一つは、受注残テーブルを別途作成する。

受注残テーブルは、トリガーを使って、最新の状態に維持する。

受注テーブルにレコード作成時にトリガー、受注残テーブルにレコードを追加。
受注取消のレコード作成時に、トリガーで、受注残テーブルから該当する受注を物理的に削除する。
出荷レコード作成時に、トリガーで、受注残テーブルから出荷した受注を物理的に削除する。

アプリケーション開発者には、受注残テーブルは参照オンリーのテーブルになる。

入庫・出庫・在庫数

似たパターンに、入庫・出庫・在庫がある。論理的には、過去のすべての入庫データと出庫データから、現在の在庫数を導出できる。

毎回導出していたのでは、処理性能の問題があるので、トリガーで、在庫数を自動更新する。

導出テーブル

受注残や在庫数は、トリガーで自動的に更新する導出テーブルです。論理データモデルとしては、対象外。過去の事実の記録テーブルだけあれば、必要な情報は、論理的に導出可能です。

受注残や在庫数は、インデックスと同じです。つまり、性能面などを考えると必要ですが、論理的には必要ない。

インデックスは、ドロップしても再作成できます。受注残テーブルや在庫数テーブルも同じで、ドロップしても、ビジネスイベントの記録テーブルから、再作成可能です。

この設計の利点

・テーブルの役割が明確。わかりやすいデータモデルになる。
・設計・開発・テスト・保守が簡単になる。
・上書き更新や削除による、過去の記録の消失が発生しない。
・速い (小さいレコードで追加のみの処理は速いです)

テーブル設計 データモデリングのエッセンス(1)

何回もデータベースを設計してきた。多くの失敗をしながら。その中から、こうすれば良い設計ができる、というデータモデリングやデータベース設計のノウハウが少し見えてきた。その要点をまとめてみる。



テーブルの役割を一つにする


クラス設計と同じで、テーブルの役割は単純にすべきである。
関心のある情報のグループごとに別のテーブルに分ける。


例えば、商品にはさまざな属性情報がある。
・仕様(色、サイズ、機能など)
・価格や割引ルール
・仕入れルート
・原価
・在庫数
・在庫場所
・販売開始/販売停止の状態や予定日
など。


「商品」という一つの「なんでもテーブル」に情報を詰め込んで、アプリケーションプログラムのほうで、さまざまな検索条件を使い分けるのは、典型的なアンチパターン。


それぞれの情報ごとに別テーブルを用意して、ひとつのテーブルは、一つの関心だけを管理する設計が基本。


役割が一つのテーブルの特徴


この設計だと、テーブルは次のようになる。
・カラム数が減る。(せいぜい10カラム程度)
・カラム名がシンプル。
・すべて NOT NULL 制約のカラムになる。


カラム数が多いテーブルだと、それぞれのカラムを識別する名前が複雑になる。テーブルの役割が単純明快で、カラム数が少ないと、カラム名も単純になる。


テーブルがさまざまな用途の情報を持っていると、レコード作成時は NULL のカラムが多く、NOT NULL制約は設定できないケースが多い。


テーブルの目的が一つだと、レコード作成時にすべてのカラムが埋まるのが普通になるので、すべて NOT NULL 制約が設定できる。


データベースリファクタリングの初歩


リファクタリングの動機になる、いやな臭いのするテーブル。
・カラム数が多い。(20以上?)
・似たような名称がずらっと並ぶ ( prefix や suffix が同じカラム )
・ほとんどのカラムが Null 値が可能である。


こういうテーブルは、複数の目的が混在している。
単純な役割を持つテーブルに分割すると、見通しがよくなり、プログラムが単純になり、保守も簡単だし、変更の副作用の範囲も限定される。パフォーマンスチューニングも容易になる。


サブタイプのテーブル設計


テーブルの役割が複雑になる、別の例。


一つの顧客テーブルで、個人と法人の顧客が混在している。顧客区分カラムがあり、企業名カラムは、個人顧客の場合は、null。氏名欄は、企業顧客の場合は、担当者名を入れる。


この場合も、カラム数が増え、似たような名称が並び、null を許すカラムが増える。
個人顧客と法人顧客は単純に別テーブルにする。個人と法人では、ビジネスプロセスやルールが異なる点が多いので、別テーブルで情報を管理したほうが、システム全体がすっきりする。


個人と法人を一緒にして(区分を無視して)処理したいケースは、ビューを使って解決することが多い。


共通情報だけのスーパークラスの顧客テーブルと、個人顧客、法人顧客の三つのテーブルに実装する設計パターンはある。顧客の区分を意識せず共通情報だけで業務が進められるケースが多ければ、このパターンもありだと思う。
経験的には、顧客区分がほんとうに意味があれば、このスーパークラスの顧客テーブルの必要性は少ない。


ビジネス分析の結果、区分の重要度をどう判断しているかが、テーブル設計に反映される、ということ。


<今日のまとめ>


カラム数の多いテーブルは、いやな臭い。


目的が単純なテーブルをたくさん作るのが良い設計のツボです。


良い設計の結果、カラム数が減り、名前がシンプルになり、カラムはすべて NOT NULL になる。


試合開始

開発範囲がだいたい決まったので、担当する技術者を集めてキックオフミーティング。

画面系のアプリケーションが中心。画面数は、主要なもので16画面。
ひとつ2週間で片付けるとして、一人でやったら32週間。4人で2ヶ月くらいの計算。

来週は、初期のドメインモデルを実装してみる。あわせてテーブル実装もやってみる。

画面まわりのメカニズムは、 Spring MVC + Velocity。
画面プロトタイプが、XHTML + CSS で作成済みの画面は、すんなり実装できるでしょう。

永続化メカニズムは iBatis を使う。実装経験は多いので、こちらも問題はなさそう。

順調に行けば、来週末には、基本動作くらいは、統合テスト環境で動いているかな?

セッション管理やユーザ認証のメカニズムを、既存のものと連携しなければいけないので、技術的には、こことが一番の問題。

これは、来週、試作検証して、なんとかメドをたてたい。

同床異夢

利害関係者が集まって、新しいトップページのデザイン案のレビュー会があった。

経営者、事業責任者、開発責任者、マーケティング、デザイナなど。

同じ画面を見ても、立場によって、人によって、興味を持つ点がこんなにも違う、ということをあらためて思い知らされました。

議論がかみあわなかった点も多々あります。
でも、誰が何を考えているかをチーム内で共有した成果は計り知れない。

オブジェクト開発の神髄〜UML 2.0を使ったアジャイルモデル駆動開発のすべて

評価:
Scott W.Ambler,越智 典子,オージス総研
日経BP出版センター
¥ 4,410
(2005-07-13)
ソフトウェア開発者がもつべき基本的なスキルを網羅した良書。

本書の特徴:

A.範囲が広い(モデリング、設計、プログラミング、データベース構築)
B.アジャイルなやり方を重視している
C.テスト駆動を重視している

範囲は広いが、実用的・実践的な内容にフォーカスしているので、現場ですぐに役に立つノウハウが満載されている。

現在のプロジェクトでも、モデリングや設計の指南書的に活用しています。

私なりに要点をまとめてみます。

人がシステムを利用する、という視点のモデリング
5章 利用のモデリング
6章 ユーザインタフェース

システムの背景・文脈を正しく理解するためのモデリング
8章 概念ドメインモデリング
9章 ビジネスプロセスモデリング

設計
10章 アジャイルなアーキテクチャ
11章 動的側面の設計
12章 静的側面の設計

実装
13章 プログラム
14章 データベース

どの章でも共通するのが、

・その局面で利用できる技法の列挙
・各技法の特徴(使用例、良い点、課題)
・どんな時は、どんな技法を使うかのヒント

を具体的に説明している点。

また、使用例や課題定義も、現場での実践経験を元にした内容で、参考になります。

最後の章で、筆者が主張している、あるべきプロフェッショナル像は、おおいに共感します。

・技術者は専門分野があるジェネラリストであるべき
・技術者は毎日の学習を続けるべき

初期のモデリング

ある程度まとまった機能を先行して開発することになった。

開発範囲のラフスケッチを描いて、中核メンバー三人で軽くレビュー。
UMLとはほど遠い手書きのスケッチ。

・ユースケース図 (らしき図)
・概念クラス図 (らしき図)
・テクニカルアーキテクチャ(free form)

の3枚を描いた。

今後の進め方、役割分担を決めた。

・各ユースケースを画面と画面遷移のスケッチ程度に具体化する。
 ユースケース数は、大きな単位で4つ。

・概念クラス図で、既存のモデルや実装部品でいけそうなところと、
 新規のモデルが必要なところの識別。
 
 仕事情報などは、HR-XML ベースで検討していたモデルがあるので、
 これを実際に作りながら成長させていけばよさそう。

 仕事情報の検索ロジックは、ちょっと複雑なことをしようと
 しているので、ここの検討がキーポイントになりそう。
 今回のスコープでは、ここがコアドメインかな?

・技術アーキテクチャ図から技術課題の洗い出し。
 特に既存システムとの連携方法。
 ここは、かなり問題が多そう。
 技術方式・実装技術の選択肢を列挙して、方針を決めて、
 試作して、動作実証できるのが、今月末かな?



人材情報の公開データモデル HR-XML

人材ビジネスに必要なさまざまな情報のデータ交換形式を
XML で標準化しようという活動がある。

HR-XML コンソーシアム

コアである、人材 ( Candidate ) 、仕事 ( Position ) をはじめ、
採用、人事評価、勤怠管理などのさまざまな情報の XML スキーマ定義 ( XSD )
が、ドキュメントやサンプル付で公開されている。

エリック・エバンスの Domain-Driven Design に
Published Language というモデル間の連携パターンが説明されている。

HR-XML は、人材ビジネス分野での唯一(?)の Published Language である。

現在開発中のシステムのドメインモデルとしても、HR-XML はかなり
参考にさせてもらっている。
(クラス名やプロパティ名でそのままの箇所もかなり多い)

「標準」という性格のため、汎用的で、使いにくい点も多い。
また、人材や仕事のデータモデリングはなかなか奥が深いので
改訂作業が続けられている。 (最新バージョンは、 2.5 )

これがあれば、すべてOKというほどではないが、出発点として
これだけしっかりしたモデルが「ありもの」として利用できるのは
ありがたい限りです。

プログラムだけではなく、モデルもオープンソースの時代。

Domain-Driven Design DDD 日本語の情報

日本語の良い情報が公開されていますね。


Domain-Driven Designのエッセンス


Domain-Driven Design テーマ:パターン

原書は、やはり読むのがたいへん。
こういう情報は助かります。

人材情報のデジタルデータ化

このシステムのドメイン(問題領域)の中核の概念は、仕事と人材。

人をデジタルデータ化して、コードで機械的に分類するのは、
正しいモデリングではなさそう。

情報システムでは、いやになるほど「人」をデジタルデータで
扱うけど、生身の人間は、そんな存在ではありません。
仕事とのマッチングという文脈であっても、可能な限り、生身の
人間の個性や感覚を大切にしたい。

デジタルデータ化するし、必要な属性だけに抽象化して、
人の持つ豊かな情報の大半は、無視することになる。
だからこそ「人」のモデルは、個性や温もりが感じられるものを目指したい。
使いやすいシステムは、こういうモデリングの
ポリシー段階から丁寧に作るべきなんだと思う。

だいたい、個人情報や、職務経歴はあまり入力したくないはず。
求職したり、応募するのだから、提示は必要だけど、可能な限り、
項目は減らすべきだし、データベースになんでもかんでも
保存してしまうのは、個人情報保護の点から問題がある。

まあ、募集企業側が、不必要と思われる個人情報入力まで応募条件にする場合が
あるので一律に情報項目を必要最小限にする、というわけにもいかないけど。
そういう企業には応募しない人は、余分な個人情報入力なしに済ませる工夫は
していきたい。

calendar
   1234
567891011
12131415161718
19202122232425
262728293031 
<< August 2007 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM