黒龍's Blog

明日から役立つ無駄知識をあなたに(仮)

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  170  : 記事  0  : コメント  2719  : トラックバック  26

ニュース

わんくま同盟に参加させていただきました。
どうぞよろしくお願いします。

自己紹介

コミュニティ

  • わんくま同盟
    わんくま同盟

書庫

えっとまずはじめに言いたいのはサロゲートvs複合キー言うな、いきなり正規化崩し言うな、第三正規形で十分って言うな。以上…じゃ全く意味不明なので思うところをつらつらと。

まず、論理設計と物理設計をいっしょくたにしてはいけません。また論理設計段階のモデリングも調査レベルから画面等を考慮したデータの合わせこみ、はたまたチューニング段階までいろいろあるので一口に論理設計といっても抽象度は結構違います。私がこういった話題を目にした時いつも気になるのは初期のモデリング時の業務要件と実装制約が混然一体となって語られているところ。いきなりサロゲートキー入れての話もいいですが思考停止や足かせになりかねないのでちょっと考えてみましょう。

で、よくあるサロゲートいるいらないのお話ですが私はサロゲートキー嫌いじゃないです。かといってオールサロゲートってこともありません。この辺り感覚で決められていることが多いと思うんですが単純にリレーション張るためっていうのも初学者に誤解を与えそうなのでドメイン(定義域)から考えてみたいと思います。

テーブル定義する際に正規化は意識すると思います。繰り返し項目を排除するってやつですね。まずは正規化されていないテーブルから考えるのですが世の中いろいろとシステム化されちゃってるのであちらこちらでサロゲートキーを見かけます。

伝票Noとか社員コードとか正規化以前を考えてもふと出てきちゃいますよね。けどこれって事象の記録には必須じゃないはずです。伝票番号がなくてもいつ誰に何を売ったかが分かれば売上の記録はできますし社員も入社日、氏名、生年月日、現住所など情報を増やしていけばユニークな識別は可能になります。

また、性別や様々な区分にしても同様でコードなんて付けずにそのまま記録して何の問題もありません。

正規化の手始めにで関数従属を切り出すのはいたって普通の手順ですがこの際にサロゲートを意識せず作っちゃってる例が多いと思います。○○コードとか作ってコード+属性値のみのマスターテーブルに切り出してませんか?

これをいきなりイメージしちゃう人は思考停止しちゃってますのでまずはやめてみないといけません。実際のところコードがなくてもリレーションは張れるのですから。(いわゆる正規化の手順の話でも当たり前のように取引先コード、取引先名等のコードありきの関数従属がありますので困ったものですが…)

そうなると「同じならリレーションいらなくね?」「コード入れたほうが容量小さくね?」「そもそもマスタいらなくね?」って言う意見はどれも正しいです。ではなぜこういったマスタがあるのかを考えてみましょう。

まずリレーションを張るにしてもコードを入れないと参照先も自身の属性も同じになってしまいますよね。ここで不要!と結論付けるのはまだ早くてテーブルを切ることで入りうる値の範囲が限定できます。これが定義域(ドメイン)をテーブルで表現したということです。性別ならば男、女、不明というテーブルを作ることでこの範囲に限定されるわけですね。数値や文字列も同じようにテーブルを設けて制限をかけたりできますがDBの機能を使って実現(型もそうですしチェック制約などの範囲チェックも同様)するほうが多いです。単純な値(性別や区分)はDBの機能でもやれると思いますがまずは値の範囲を規定する、その実装はテーブルでもできるしDBの機能でもできる。という思考手順を踏んだほうがいいと思います。

単純な属性値ひとつじゃない複数のケースも同様で値の組み合わせに対してとりうる組み合わせををテーブルに記録します。

じゃなぜコードを入れるの?って話になるんですが容量的な意味合いと変更可能性が主な理由になります。男、女など意味は変わりませんが表示項目としてとらえるのであれば十分に変更の可能性があります。まずそもそも定義域としての流れなので変更可能性を考慮して表示項目は別に設けたほうがよいでしょう。

テーブルイメージだとこんな感じですね。

識別子 属性値
男、女など 男性、女性など

男とか女とかダイレクトに書いてあるとコードっぽくないですが意味わけされたのでこれでも立派にコードです。画面項目ではなく区別するために導入されているのでコードもサロゲートキーであると言えると思います。

組み合わせ項目にしても同様ですが容量的にも無駄が多くなりますから○○IDなんて付けたりします。流石にコード体系考えて人が意識して何かの識別子をつける意味もあまりないので数値の連番を振ったりしますね。

結局のところコード+属性値という形はきちんと正規化された形ではあるのですが丸暗記的な思考停止ときちんと意味を考えながらでは意味合いが変わってくると思います。

実際のところチューニング意図を踏まえてどんどん正規化していけばかなりの項目が自然とサロゲート+属性値になるのは確かなんですがきちんと説明できない場合や複合キーがあまりない場合正規化度合いの低い状態で早期の思考停止になっちゃってませんか?

正規化の最終段階での制約の除去と未正規化テーブルのビジネスルールの消失をまぜこぜにしないように。

ちょっと長くなったので今回はこの辺で。

投稿日時 : 2009年6月6日 16:21

コメント

# re: そのコードサロゲートにつき…カオスなモデリングにモノ申す 2009/06/06 22:16 がんふぃーるど
理解して物事を行うのは重要ですよね。

物理よりな話でも、パフォーマンスを上げるために縦持ちになっているテーブルを
横持ちにすれば必ずパフォーマンスが上がると思っている人とかいたりしますね。

同じブロック(もしくはページ)に格納されるから物理IOはある程度改善されるのですが、
アクセスパスによってはハッシュ結合で出来ていたものが、ハッシュ結合を使用できなくなったりするので
ものによっては横持ちが不利に働く場合がありますね。(Oracleならbitmapインデックスなどで対応できる場合もあるけど)

ただ、忙しい時などはつい経験で判断したり、周りのものを真似てしまい、思考停止してしまうときがあります。
後々見るとちょっと良くない設計したな~なんて後悔するのですが、時すでに遅し。
あのときに誰かが私をぶっ叩いて、目を覚ましてくれればいいのですが・・・


# re: そのコードサロゲートにつき…カオスなモデリングにモノ申す 2009/06/07 0:21 Ognac
同意。物理設計の項目と物理設計の項目差を認識していない現場は、往々にありますね。
私は、永久連番キーをサロゲートにすることが多いのですか、勿論論理設計書には登場しないです。
論理設計書は、 売上伝表-->顧客マスタ で意味が通じる思うのですが、連携キー項目が抜けているという理由で、レビューに引っかかることがあります。
その時に困るのが、連番サロゲートです。売上伝表(顧客連番)-->顧客マスタ(顧客連番) では、説明を求められ、顧客コードに直されたりします。
論理設計に物理項目名は不要だと考えているのですが、そうならない現実がありますね。

縦持ちすべき項目を横持ちするのは、コメントのように、データ取得が 行単位によるIO回数という認識が抜けないからでしょう。
正規化崩しが妙に流行って、高速化のため関連項目を横持ちしてます。と正当化しているプロジェクトも見かけます。
双方のテストパターンを作って実験すれば直ぐ結論がでるのですが、未検証で、思い込みで主張するのも見かけますね。


# re: そのコードサロゲートにつき…カオスなモデリングにモノ申す 2009/06/07 0:43 黒龍
> がんふぃーるどさん
横持ちは基本的に不利でしょうね。更新時のロック範囲を考えるとあり得ないです。
そもそもチューニング意図なのであればインデックスの附加列やインデックス付ビューなどで目的は達成できる(かつメリットは多い)なので思考停止の言い訳にしちゃダメですよね。
とはいえ私もタイムマシンがあればほとんどのプロジェクトで自分をぶったたきたいですが^^;

>Ognacさん
調査時の概念レベルならおっけーですが論理設計段階でもコードは入れていったほうがいいかもしれませんね。おっしゃるように実際の項目名やDBで振り出すのか採番テーブル使うのかは物理設計の範囲かと思いますが。
連番サロゲートも二元論で語らずにPKは連番キー、顧客コードを二次識別子(ユニークインデックスorPKでない一意キー)で入れ込んでおくってのもありだと思います。基本設計時の記述、レビューは二次識別子側で記述。詳細設計、コーディングは連番キーで…みたいに。
うまくこういったことを若い子たちに伝えていきたいですね。


# re: そのコードサロゲートにつき…カオスなモデリングにモノ申す 2009/06/14 2:29 れい
続き希望です。

Post Feedback

タイトル
名前
Url:
コメント