データベースの不吉な臭い
近頃はドメイン駆動に興味の中心があるせいか、RDBの論理設計についての話をあまり聞かなくなってきた。
では、みんなよい設計ができるようになったのか?いやいやそんなことはない。よくひどい設計に当たったりもする。
よいデータベースの論理設計って何か?という問いに対しては、「データベース・リファクタリング」の「データベースの不吉な臭い」がとても参考になる。今まで見てきたひどいデータベース設計のほとんどがこのアンチパターンに入っているように思います。
- 複数の目的に使われるカラム
データベースリファクタリングで挙げている例は、顧客の場合には誕生日を、従業員なら雇用開始日を格納する開始日付項目。「そんなことしないよ」と思われるかもしれませんが、経験上、この手は以外に多い。
たとえば、テーブルにありがちなシステム管理上の「データ作成日時」を、運用上一致するからといって「申込日」といった業務上の日付として扱ったりするようなパターン。身に覚えがありませんか?(複数の目的に使われていること、わかりますか?) - 複数の目的に使われるテーブル
データベースリファクタリングでは、Customerテーブルに個人と会社の両方の情報を格納している例を挙げている。これもなかなか多いパターンで、以前は本当によくありました。ひとつのフォーマットに複数のデータを混ぜたがる人がいるんです。特徴は、データの種類ごとにNULLになるカラムが決まっていることです。 - 冗長なデータ
データベースリファクタリングでは、他のシステムとのデータ重複を挙げています。これもよくある話で、むしろシステマティックに上手に解決しているところの方が少なそうです。 - カラムの多すぎるテーブル
これも多い。データベースリファクタリングでは、「凝集度が低いしるし」と書かれています。細かく切り刻みすぎなテーブル設計はあまり見ませんが、こちらの方はよく見ます。先ほど出てきた、「複数の目的に使われるテーブル」なんていうのも大抵カラムが多すぎます。 - 行の多すぎるテーブル
これはどちらかといえば、性能の問題です。中にどのくらいのデータが入るのか全く意識しないために想定外のデータ量が入ってきてしまうというパターンですね。設計するときに、どのくらいのデータがはいるのかぐらいはある程度想定しておこう。(せいぜい数十件レベルなのか、万単位のデータが入りそうなのかぐらいは区別できるはずです。) - 「スマート」カラム
これは最近はあまり見なくなったのですが、かつてはよくありました。たとえば、固定長コードの上4桁が店舗コードで、その次2桁が分類を表し、その後4桁が連番とか。でも、汎用機をいじっていたころは、みんなこんなコード設計をしていましたね。RDBでは、こういうものはちゃんとカラムに分けて、個別に扱えるようにするのが基本です。 - 変更の恐怖
で、みんなビビッてます。実は当然で、以前は「DBのスキーマを変更する必要がある案件」=「工数がかかる案件」ということになっていた気がします。
いろいろと「データベースリファクタリング」から「データベースの不吉な臭い」について書いてみましたが、RDBの論理設計は、実はこれだけ気をつけて設計すれば、案外いけるのではないかなあと思っています。
RDB の設計は、いまでも、とっても重要だと思います。
ドメイン駆動は、クラスのモデリングが中心なので、実装も、Java や C# からの視点が強くなりがち。
でも、エンタープライズアプリケーションは、DB(永続化)が重要課題だし、OR マッピングが大きな実装課題。 PoEAA のORマッピングの議論も、ひととおり押さえておきたいものですね。
増田さん、コメントありがとうございます。
そうですね、エンタープライズには永続化がつきもの。
そこを上手に作るのは大事ですね。