RDB正規化のお話

なにやら正規化の話題が出てるので首を突っ込んでみる。
元ねたは正規化で悩んでた

* 第三までは、雑念(実装効率とか)にとらわれずにきっちりと行う
* 正規化を崩して良いのは、それ以降の話
* それ以前にやめる人は、RDBモデルの特性をちゃんと理解していないか、手を抜いているだけ。後でつけを払うことになる
* 正規形を崩すのは、物理的問題(ディスクIOなど)を考慮する必要がある場合で、かなり高度。判らないうちは崩さないほうがいい

まぁ、そうでしょう。
少なくとも解析の段階では実装や物理制約のことなんか考えちゃいけない。

注意しなければいけないのは2つ目にでてくる『それ以降』。つまり設計の段階ではそれまで排除していた実装や物理制約を念頭に入れないといけない。そして正規化を崩すことも考える。

上の記事を参照してkomagataさんが

JOINは遅いのではなく、「遅くすることができる」ってだけで、エンティティが意味的に正しく抜き出せてれば(Index使って)何個JOINしても一瞬で返ってくるっつーの!

と言っているが、これは『それ以降』を無視している。

確かにIndexを使えばJOINは格段に早くなる。しかしそれでもJOINにコストがかかるのは事実。Index利用のSortMergeJoinだとしても、{R}+{S}-1*1の比較が発生する。その上テーブルが大きくなればJOINした結果をディスクに一時的に保管するためディスクI/Oが発生する。
今はメモリがふんだんにあるのでディスクI/Oは発生しにくいが、いくつもJOINしてたらそのうちメモリも足りなくなる。同時多発したらなおさら。

したがって大きなテーブルに対して頻繁にJOINが発生するのであれば、非正規化を検討する必要がでてくる。
こういうのが最初にあげた項目の4つ目に当たるんだと思う。中身知らなきゃわからないことだけど、 「正規化しなくてもいい」という迷信を排除しようとして、「JOINはいくらしても平気」なんていう神話作るのは良くないと思っちゃいます

一人で要求定義を行い解析をして設計をするとなると、全部いっぺんにやって仕舞いがち(少なくとも頭の中では)だけど、分けて考えるのも必要ってことですね。

*1:{R}は関係Rのタプル数