|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2012 2010 2009 2008 2007 |
May 21, 2010. DBの高速化についてA
前回の続きです。
冗長化 データベースを勉強するというと、最初に登場するのは正規化の話だろう。得意先は得意先マスタへ、商品は商品マスタへ、重複するデータはコードを持つマスタに切り分けて、閲覧時に結合するよう処理する。 正規化の利点といえばデータ量の削減が第一にあげられる。また、巨大なテーブルを構築するよりデータの抽象的読解が楽になるという利点も有る。開発者なら実感できる利点としては、プルダウンなどの画面構築が楽になる点も大きい。
上記のような利点が説明され、データベースの学習の初期に習うことから、正規化こそが理想形であるという、正規化の正義化がなされているように思う。しかし現実的には正規化にも欠点は多い。例えば過去ログ管理の難しさや、速度問題などである。
前者は理想的なシステムであれば問題にならない。マスタは使いまわさない。データは消さない。そういうシステムだ。しかし実際にはそれではうまくいかないシステムも多い。 例えば、何らかの販売システムを作った場合、商品コードは一意な結合キーとして用いられるのが普通だ。商品コードの使い回しはしないのが普通である。しかし、お客さんから以前使った商品コードを使い回したいと依頼を受けることはある。 拒絶したいところではあるが、実際に同じコードで商品を作られた後で依頼は降りてくるし、上位システムからは同じコードで違う商品の情報が落ちてくる。対応せざるを得ないので、マスタのコードを再利用すると過去の販売履歴データの内容がおかしくなってしまう。商品名が変わってしまうだけならまだしも、場合によっては情報が不整合を起こし、画面を開くだけで落ちるようになったりする。仕方なく過去ログを退避させたり、という無駄な作業が発生しうる。最近では市町村統廃合により郵便番号系のデータで同様の問題が発生しがちだ。 「だったら、商品コードとは別の内部コードで結合するよう設計すべきだ」との言い分もあるかもしれないが、全部のコードを二重管理する羽目になる。ちょっと現実的ではないだろう。(注文番号など、一部の番号はシステム内でそのように管理することも多いが)
後者はまぁ、考えればすぐわかる話。ある注文データにコカコーラが含まれていたとする。正規化すると、発注TBLには商品コードAAAを、商品マスタにAAAA,コカコーラのようなデータを持たせる事になる。一覧表示の際には結合して表示することとなるわけだ。 この商品マスタが、数千件の場合にはなんら問題は起きない。しかし、Amazonのような巨大販売サイトだとどうなるか。世界中の人間の発注データに対し、世界中で販売されているありとあらゆる商品---例えば書籍だけで1千万件という巨大なアイテムマスタと結合の上で表示を行なう羽目になる。まともに設計したら酷いパフォーマンスになる。 無論、ジャンルごとに分割したマスタ、適切なパーティショニングやインデックス化などを行なえば、ある程度のパフォーマンスは確保できるだろう。しかし、日々更新される商品群の存在を考えると、過去の注文履歴の参照にまでマスタ参照を行なうのはあまりに不毛だ。
とまぁ、これらを解決するのが冗長化である。マスタはマスタとして持っておくのだが、発注情報を確定したら、マスタの持つ必要項目を発注TBLに持ってしまうのだ。当然データ量は増える。しかし参照コストは減るので、場合によっては大幅な高速化が見込める。また商品マスタなどのIDを使い回ししても、過去ログに影響が出ない。 利点はそれだけではない。例えばBtoBで得意先がマスタに全て登録されている前提のシステムがあったとする。発注データに得意先マスタのIDだけを登録するのではなく、冗長構造で必要な得意先情報も保存するように設計しておいた場合は、BtoCなお買い物サイトなどにもそのまま適用することができる。クラウド等を想定するなら今後必要な発想といえるだろう。 ※パスにはこの日記のタイトルをコピペして下さい。 d:d -2011/02/02 17:59:42 Copyright 2010 barista. All rights reserved. |
|