設計者の発言

業務システム開発とデータモデリングに関する語り

基本のキ「簿記のデータモデル」を学ぼう

 エンタープライズシステム(業務システム)は「仕訳入力システム」が発展したものだ。もともとは伝票形式で勘定科目を指定する形だったが、個々の業務に特化することでユーザは科目を意識しなくてよくなった。同時に、各業務に固有な管理項目を取り込むことで、業務データのステータス管理が可能になった。とはいえ、ユーザは気づいていないがシステム連係の裏側で個々の会計取引は仕訳に変換されている。

 それゆえ、システム開発者には簿記の知識が欠かせない。簿記3級レベルの基礎知識はもちろんだが、その「データモデル」が把握される必要がある。そうでなければ、会計システム(仕訳プロセッサ)との連係を果たせない。

 業務システムの開発者が身につけるべき基本のキとして、仕訳プロセッサのデータ構造、すなわち「簿記のデータモデル」を説明しよう。「貸方・借方」の意味合いや決算プロセスについては割愛するので、そこらへんを含めて理解したい読者は簿記の学習書や拙書「データモデル大全」を参照してほしい。

簿記のデータモデル

 まずは全体を俯瞰しよう(図1)。「勘定科目」を年月展開したものが「科目別月次サマリ」で、そこで月次の勘定残高が保持される。ふつうは年度や四半期といった他の会計期間別のサマリも伴うが、ここでは省略されている。「仕訳明細」は「科目別月次サマリ」への参照関係を持っており、仕訳額が月次集計されて勘定残高の算定基礎となる。なお、仕訳明細上の「年度」と「月度」は仕訳見出し上の「取引日」から導出されたものだ。導出項目(カッコ付で表現される)を含めた形で仕訳明細から科目別月次サマリへの参照キー(外部キー)が構成される「動的参照関係」の例になっている。

図1.全体のモデル

 なお、ここに「試算表」や「総勘定元帳」が含まれていないと思った読者がおられるかもしれないが、それらはこのデータ構造から簡単に出力できる「ビュー」でしかない。それらがデータモデルに置かれているとしたら「冗長」という意味で間違いである。こういった間違いは、既存の画面や帳票といったUIを手がかりにしてモデリングすることで頻出する。気をつけてほしい。

 続いて、具体値付きで部分毎に確認しよう。まずは「勘定科目」の系列だ(図2)。1企業あたり100個程度の勘定科目を扱うが、それぞれで決算書上の位置づけ(勘定区分)と階層関係(上位科目C)が決まっている。階層関係を表すために自己参照が効果的に使われている。勘定科目を年月度で展開したテーブルが「科目別月次サマリ」であり、年月度別のさまざまな集計値が保持される。「仕訳明細」上の仕訳額がどのように集計されているかをじっくり確認してほしい。

図2.勘定残高のモデル

 なお、勘定科目毎に貸借が決まっているので、仕訳明細に置かれた貸借区分は一見すると正規化違反のように見えるがそうではない。初学者が混乱するところなのだが、借方の勘定科目が貸方に仕訳されることがふつうに起こる。その場合、その仕訳額はその科目の貸借の反対側の合計額として集計され、月末残高(現残高)は科目の貸借側合計額を加算要素、反対側を減算要素として算出される。

 図3は「仕訳(仕訳伝票)」である。簿記の正式名は「複式簿記」で、複式とは貸借のそれぞれに勘定科目を指定することを意味する。ひとまとまりの取引が「複数(2個以上)の勘定科目価額の動き」として認識される点が、小遣い帳や大福帳のような「単式簿記」との違いである。

図3.仕訳のモデル

 「仕訳見出し」上の仕訳合計額は、借方合計額と貸方合計額を表すが、貸借の合計額は一致するので1個しか置かれていない。つまり、仕訳見出し1件に対して、複数件の仕訳明細が対応するが、借方と貸方はそれぞれ少なくとも1行は存在する。複数存在しても、借方合計額と貸方合計額とは一致する(貸借一致の原則)。

 こういった仕訳登録の際の制約や残高計算のルールは、かつてはアプリ中のコードとして表現されていた。データモデルはそれらを(部分的であっても)データ構造に回収するために構想される。さらに現代的な開発基盤(ドメイン特化基盤)では、テーブル自身がそれらをビジネスルールとして保持できるようになった。こうした工夫によってアプリはどんどん軽薄短小化し、設計者自身が片手間で作れるものになった。これもITによる合理化の一環で、ITは自分自身さえ合理化のターゲットにしてしまう。

単独主キー主義の不合理

 ここまでの説明を読んで、{科目C+年度+月度}や{仕訳№+行番}のような複合主キーを避けたいと考えた読者がいるかもしれない。まったくお勧めできないが、無理にというのであれば、「サロゲートキーの導入」と呼ばれる高度な正規化崩しの手順を踏まねばならない。

 すなわち、idや№のような単独主キーを付与すると同時に、もともとの複合主キーにユニーク制約を与え、それらの値がアプリによって更新されない工夫を施すといった手順を踏む。しかしこういった辛気臭い調整が完遂されることはまれで、たいていは抜け漏れだらけのテーブル設計になる。そんな例が図4だが、実際はもっと悲惨で、テーブルの主キーがすべて{id}だったりする。

図4.複合主キーを使わない簿記のデータモデル

 この手のモデルにもとづいてシステム開発する者の苦労を想像できるだろうか。このモデルで言えば、とくに頭を抱えるところは科目別月次サマリと仕訳明細との参照関係あたりだ(赤で示してある)。{科目C,年度,月度}が本来の主キーであったことを知らない詳細設計担当者は、仕訳明細上の「科目別月次サマリid」にどんな値を設定すればいいのかわからない。こんな単純な事例でも、本来のデータモデルが含んでいた豊かな「意味」が失われてしまう。複雑なモデルでは問題はさらに深刻だ。

 ちなみに、オブジェクト指向言語(OOP)でDBシステムを開発する場合、全テーブルの主キーを{id}にすることを強制するORMフレームワークが利用されるのがふつうだ。じつはこれがさまざまな問題の元凶となっている。本来であれば丁寧に正規化崩しの手順を踏むべきところを、多くの設計者が最初から主キーを機械的にidにするスタイルで設計してしまうからだ。

 ただでさえ主キーが歪んだDB上のデータ整合性を膨大なコードで制御することになるので、開発にも保守にも無駄にコストがかかる。一部の技術者はドメイン駆動設計を頼みの綱とみなして難解な関連本を読み漁るが、業務システム開発OOPとORMを適用することがそもそも悪手であることに彼らは気づかない。前回記事でも書いたように、OOPは「ドメイン特化基盤」を開発するための「ハレの手段」とみなしたほうがいい。

イミュータブル・データの特殊性

 なお、上述した「仕訳テーブル(図1の3,4)」は、最近耳にする「イミュータブル」、つまり、追加されるばかりで更新されることのないデータである。ある取引にもとづいて仕訳データを登録したが、その解釈に間違いがあったとしよう。その場合、まず「赤伝」を登録することでもともとの仕訳を訂正(相殺)し、あらためて正しい仕訳(黒伝)を登録する手順を踏む。これを「赤黒訂正」といい、会計上の不正を防ぐための独特な措置である。いっぽう、「科目別月次サマリ(同2)」は仕訳登録や決算のたびに更新され続けるのでイミュータブルではない。マスターデータも更新され得るので「勘定科目(同1)」はイミュータブルではない。

 イミュータブルなデータというものはたしかに存在するが、どちらかというと特殊なケースで、そのあり方を敷衍してデータモデリングのスタイルや指針になるわけではない。ある種のデータはステータスに応じて(あるいは無条件で)更新や削除が禁止される、という固有の問題でしかない。ふつうに更新されていいデータを無理にイミュータブルとみなせば、システムは無駄に複雑化してカオスに落ち込むだけだ。

 全テーブルをidのような単独主キーにするやり方といい、イミュータブル・データモデリングといい、ある種のテクニックでデータモデリングの難しさを回避・緩和できるといった言説を信用してはいけない。データモデリングは高層ビル建設における構造計算のように、複雑かつ高度な専門スキルである。習熟することは簡単ではないが、いったん身につけたらシステム開発者のキャリアを支え続ける人的資本になる。簿記のデータモデルからはそんなことも学んでほしい。