[pgsql-jp: 35090] Re: 正規化しない方がよい場合というのはどういう時なのでしょうか?

水野 圭 kiyoshi_mizuno @ mail.toyota.co.jp
2005年 3月 23日 (水) 08:19:06 JST


水野です。

すでにtomsonさんから発言をいただいていますが、
発言者として私も書かないといけませんね。

> -----Original Message-----
> 上記の発言の元の質問では、複数のテーブルをリンクさせており、
> しかもそれらをロックしていないと、nextvalで問題が発生する。
> というように読めています。
> そのため、全部をロックしなくてはならないなら1テーブルにした方が…
> という発言になっているのかなと、推測しているのですが、
> 私自身が正規化すべき場合とそうでない場合の切り分けが
> できていないことに気づきました。
> 
> リンクされたテーブルを幾つもロックして更新しなくてはならない
> ため、以外にも「あえて正規化しない方が良いと考えられる」ケース
> というのもあるのでしょうか?
> どう判断して、今回は正規化するorしないを判断したらよいのか
> の物の考え方を教えて頂けないでしょうか?

まず前半5行はechoさんの認識どおりです。

> どう判断して、今回は正規化するorしないを判断したらよいのか
> の物の考え方を教えて頂けないでしょうか?

で、肝心なここなのですが、残念ながら私にも人に「こうだ」と言える理論的/経験的
根拠は持ってません。

今回の場合、
「トランザクションを単一テーブルの行レベル読込排他ロックに縮小できないか?」
という単純なアイデアとして発言しています。

私の知っているRDB(といっても中身を知っているのはPostgreSQLとOracleぐらいだが)
ではユーザアプリケーションからのSQL文をまず文法解析して「実行計画」というのを
作成します。(これは同一SQLを何度も発行したときにはキャッシュとしても
機能します。)
PostgreSQLならexplain句(だったよね?)を使うとこの実行計画を見ることが
できるのですが、当然ながら3テーブルをリンクさせたSQLより1テーブルの
SQLの方が簡単になります。この差があまりにも大きいなら正規化を崩す理由の
1つにはなるでしょう。

ただこの方法を安直に薦められないのは、元のテーブルの構造
(今回の場合A,B,C)によっては1つのテーブルに合成する事で新テーブルに
無駄な領域(空カラム)が大量に発生する可能性があるからです。

というか大抵そうなるので、完全に1つに合成するのではなく
「二重定義になるけどトランザクション成立に最低限必要なカラムを
 どれかメインの1テーブルに定義し、1テーブルでのトランザクションにする」
 &
「トランザクション完了後、別トランザクションで他の2テーブルのカラムに値をコピーする」
という形に落ち着かせる事が多いと思います。
非常に不自然なロジックになりますので、アプリ側でも細心の注意が必要です。

システム要件によって
「ディスクで無駄を出してでも応答時間を短縮する」
という状況もありますし、
「ハード制約が厳しいからきっちり正規化して最小のデータ領域にする」
という状況もあります。

そのため私からは「ケースバイケース」で、としか言いようがないです。




pgsql-jp メーリングリストの案内