#10 - データベースのデザイン
データベースは企業活動にとって大切な情報を保管し利用する器である。
ネットワーク型、ツリー型、リレーショナル型、また、リレーショナル型を応用したオブジェクト型というのもある。
現在の企業活動で最も多く使われているのはリレーショナル型ではないだろうか?
日本国内においては、1980年代の後半まではネットワーク型、ツリー型が主流だったと記憶している。特に、銀行などのオンラインシステムを支えているのがそうであった。その後、IBMやOracleなどがリレーショナルDBを世に送り出していき現在ではリレーショナル型はデータベースの標準になっている。元々はIBMのコッド博士が考案したのが始まりだ。
ネットワーク型やツリー型といったデータベースをデザインする場合は、検索や更新する際のキー情報を先にデザインしないと作ることができなかったし、作成後にキーを変更するということはデータベースの変更作業となり大変な作業だったが、リレーショナル型は、データの部分とキー項目の部分を別々でデザインできるため設計の柔軟性が格段に向上した。当初は、パフォーマンスの問題も指摘されていたが、現在ではすでに解消されデータベースの標準の地位を確立している。
このリレーショナル・データベースをデザインする場合、業務処理を効率よく行いデータの保守や分析も効率よく実施できることを想定したデザインということも考えるべきである。つまり、更新頻度やテーブルの特徴を考慮したりして普段実施する処理速度が変化しないようにできれば日々予定した時間内で処理が完了するように利用できる事になる。これはユーザーからのリクエストによる処理だったり、バッチで一括処理するケースの両方に当てはまる。
過去のデザインにおいて、私が考慮してきたことの一部を紹介する。
1. データ量の考慮
入力されたデータがそのまま徐々に溜まっていくようなテーブルの場合は次第に容量が大きくなり、そのテーブルに対する処理が遅くなってしまうことになる。
SQL処理で一定の処理スピードを保持しようと考えるのなら、テーブルの容量は一定に保たれるのが理想である。
蓄積され続けるテーブルの場合の多くは、日々のトランザクション・データの特性を持ったものが多く、月末処理でデータが確定されると「日々利用するデータ」から「保管データ」へと変化し、日々の処理での参照や更新は極力少なくなるケースが多い。であるならば、同じテーブルの中に「日々利用するデータ」と「保管データ」を混在させるメリットは少ない。分離してしまえばいいのである。例えば、当月分のテーブルと前月分とか前年分とかのかたまりでテーブルを作って保管データを移動してしまえば、データ量の大きな変動を作らずに済む。このような処理に関しては、データベースのトリガー機能を使って異なるテーブルに移動するということも考えられる。
テーブルを分割した場合でも、必要であれば、Joinして一つのテーブルのように処理することが可能なので、テーブルのレイアウトは合わせておくと後々処理しやすくなるだろう。
2.インデックスの利用方法
リアルタイムで利用する時は大抵が任意のデータをピンポイントで参照したりすることが多いが、その逆に単純にデータ収集のみしか実施しない場合は、データ収集した後に一括して処理するということも考えられる。その際、リアルタイムではデータ収集のみなのであれば、インデックスをつけないという選択もある。そして、まとめて処理をする直前で必要なインデックスを生成して処理を実行し、終了したらリアルタイム処理のために、インデックスを削除しておくということも考えられる。そうすることで、インデックス更新にかかる処理をリアルタイムの時には考慮しなくてよくなり、インデックスがついていることによるデッドロックの心配もなくなる。
リレーショナルデータベースの場合は、インデックスを後からつけたり独立して削除できるのも大きな特徴の一つである。この特徴を利用したデザインもあって然るべきだ。また、データ部分が少ない場合、全てをインデックスとして定義すれば、データ部分を読まずにデータを取得することもできるようになる。例えば、カウンターのような項目が必要なときなどに利用することが考えられるわけである。
3.分析するための考慮
過去のデータは、予測や分析を実施するのに重要である。データベースを作成するときは、通常、作成された日時や、更新した日時、削除した日時がデータベースのログには記録される。しかし、それらを一括してユーザーが処理しようとするとSQLの発行だけでは処理できない。ということは、各テーブルの中にこれらのフィールドを定義しておき、削除は物理削除ではなく論理削除(フラグを作って削除の意味合いを持たせる)にしておくことで、SQLの発行で把握できるようになる。
例えば、製品別季節別注文の件数/金額推移や最もトランザクションの多い月の把握などが容易にできるようになる。たったこれだけの考慮でもかなり分析には役に立つのではないだろうか?
私は、日々の新規登録件数、削除件数、更新件数をグラフ化して管理することで、システム管理要員がデータ量の増減を把握し、適切に要領増加の判断ができるようにしたことがある。応用としては、製品単位などで分析すれば季節変動などの傾向をプログラムを作成することなく簡単に取り出すことができるだろう。
4.集合操作しやすいテーブルの考慮
一つのテーブル内に毎月のデータを保管するための項目を12個準備し、その合計用のフィールドも定義するというデザインを時折見かけることがあった。また、同様に年単位の合計テーブルというものまで作られていることもあった。せっかくのリレーショナルデータベースなのに計算すれば求められる合計値まで持っておくのは処理スピードの問題を起こさないためだと思うのだが、データ間の不整合を引き起こすリスクを内在していることになる。どちらかといえば、後者の方が始末に悪い。従って、合計はSQLで算出するようにするように考慮してデザインした方がいい。
過去に利用していたデータベースから移行した場合にはプログラム変更を避けるためにテーブル定義をそのまま過去のデータベースに合わせてしまうことがよくあったが、本来は移行の際も極力データベースの特性を活かせるデザインを採用する方がいい。一旦稼働させてしまうと大幅な変更はやはり大変な作業になるのである。
実際にデザインする時は、正規化とともに業務の特性を考慮しなければならないので、単純には考えられないが、データを情報として使い続けて行くための考慮は心がけるべきである。単に保管しているだけのデータにしないためにも。