理論から学ぶデータベース実践入門 ch6 ドメインの設計戦略 2/2
IDを設計するという考え方
現実世界の物体や概念を表す手段
- DBに格納するIDは、現実世界の物体や概念を表すもの
- 物体や概念を集合で表現するのがリレーショナルモデル
- 1つの属性が1つの物や概念と対応する
- IDが物や概念との全単射であるかは設計次第
- 一意になるような設計を人間がすることによってIDはIDとして機能する
- 【補】
- 【補】GitやDockerでハッシュをIDとして使用しているのも関連する話か
- 理論的には衝突が発生し、一意性が崩れる
- が、実運用上扱うもの(ファイルやコンテナイメージ)の数に鑑みて、衝突することはないと想定
ナチュラルキーとサロゲートキー
- 著者見解: いずれもRDBにとっては必要
- どちらか一方を排するべき、というのは暴論
- 本質的な違いはなく、すべて人工物である
- 「自然キー」とはいうが、宇宙の摂理として存在するわけではない
- 過去にほかの誰かが割り当てたか、自分で新しくIDを割り当てるかの違いしかない
- 用いる値がIDとして機能し得るものか、が本質
- よくあるダメな例: 名前
ナチュナルキーの使いどころと問題点
- すでに誰かが運用し・何かを識別でき・長期に渡り値に変更がなく・信頼できること
- 基礎年金番号とか
- IDのライフサイクルを吟味せよ
- IDを発行した機関が、システムのライフサイクルよりも十分に長く運用を継続してくれること
- 権威があるように見えるIDであっても、実際には運用が失敗することも
- ISBN
- 何を特定するものなのか吟味せよ
- 例: e-mailアドレス
- あくまでもe-mailアドレス自身を特定するもの
- 人を特定するものではない
- 例: e-mailアドレス
サロゲートキーの使いどころと問題点
- OK
- 識別したい対象の物や概念を表すIDがいまだこの世界に存在しない
- NG
- 不要なサロゲートキーは関数従属性を生じてしまう
- DB設計を無駄に複雑化する
リレーショナルモデルにおけるキー
- ナチュナルキーやサロゲートキーはリレーショナルモデル上の概念ではない
- リレーショナルモデルにあるのは候補キーとスーパーキーのみ
意味を含んだID
- 「青いサイクロン式の掃除機」の製品コード
CLN-CYC-0123-BL
- CLN: 掃除機
- CYC: サイクロン
- 0123: 世代?
- BL: 色
- このような属性を定義すると1NFではなくなる
- 列の値がアトミックではなくなるため
- 個々のパーツを個々の属性として定義せよ
- くっつけるのは表示上の問題であり、データの本質ではない
- こういうときにサロゲートキーを導入するのは悪い選択肢ではない
- 製品コードを個々のパーツに個々の属性に分けると、製品と1:1で対応するIDとなる属性がそのリレーションに存在しなくなるから
紙の呪縛
- 人間が視認しやすいIDを推す人々が存在する
- 「帳票に印刷したときに見やすい」
- 「ITシステムが止まっても、紙を使って、業務を遂行できる」
- 紙の文化がITシステムに侵食しDB設計を歪めてしまう
- 「表示上の問題はDBと分離せよ」という考えに反している
IDの欠陥は波及する
- あるリレーションのキーは別のリレーションにも登場する
- 外部キー
- IDの選定をしくじるとあらゆるリレーションに影響が及ぶ
色、長さ、重さなどの性質を表す属性
{製品ID, 製品カテゴリ, 製品カラー}
という属性をもつリレーションの述語をP(x,y,z)
とする
性質を述語と解釈すると、リレーショナルモデルでは扱えない
- ある物体
c
が「黒い」という述語
Black(c)
- cが黒ければ真、さもなくば偽
P(x,y,z)
のz
には述語Black(c)
が入るP(x,y,z)
は述語に対する述語となる- このような述語を扱えるのは二階述語論理であり、リレーショナルモデルでは扱えない
「集合にラベルをつけた」と解釈すればリレーショナルモデルに適合する
- 「黒」という色の名称、すなわちラベル
Black
P(x,y,z)
のz
には値Black
が入る- 一階述語論理なので、リレーショナルモデルに適合する
- 個々のラベルに重複がなければ、性質という概念を識別するIDとして使用できる
SQLによるドメインの表現
適切なデータ型を選ぶ
- SQLのデータ型はドメインと必ずしも1:1対応しない
- 最低限、ドメインの持つ値をすべてカバーできること
- 最もよくそのドメインの特徴を表すデータ型を用いること
- 本質的に数値であるものを文字列型で表すのはNG
- 無駄にデータサイズ大きい
- 数値としての演算を行えない
- 本質的に数値であるものを文字列型で表すのはNG