fc2ブログ

makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

SQLアンチパターン読書会 「続・IDリクワイアド」 に参加しました

2013/5/23(木) SQLアンチパターン読書会 「続・IDリクワイアド」 に参加してきました。

DoorKeeper
http://sqlap.doorkeeper.jp/events/3968

以下の書籍をターゲットとした読書会なのです。
SQLアンチパターンSQLアンチパターン
(2013/01/26)
Bill Karwin

商品詳細を見る


会場は湯島(御徒町)のアルティネットさんです。
主催者の @natsu_nanana さん、会場提供の @heroween さん、いつもありがとうございます。
参加者は全員で9人かな。今回も訳者の @t_wada さん参加です。頼もしい!

今回は前回に引き続き、3章「IDリクワイアド」がターゲットです。
というのも、この章はみなさん思い入れが強く、前回だけではディスカッションが尽きなかったのです。
前回のブログはこちら。




■3章「IDリクワイアド」の発表
by @osa2 氏
20130523_sqlap_1.jpg
(クリックするとDropboxにある資料に飛びます)

2度目の発表です。いつもありがとうございます。
ちなみに背景の画像は、以下のサイトにあるER図から取ってきたそうです。
http://laurel.datsi.fi.upm.es/~ssoo/DAW/Trabajos/2008-2009/022/

このER図、良く見ると・・・ 「あ、これ 進研ゼミ SQLアンチパターンでやったやつと同じだ!」


■各テーブルにカラム「ID」が!? こ、これはまさか「IDリクワイアド」・・・!
■Categoryテーブルのカラムに「Parent」が!? こ、これはまさか「ナイーブツリー」・・・!

ってな感じで感心しつつ、ワラタw
つーか、こんな題材よく見つけてきましたね~

あと、スライドP.8以降で「達人に学ぶDB設計徹底指南書」というミックさんの書籍から抜粋があります。
達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ
(2012/03/16)
ミック

商品詳細を見る

この書籍から代理キーをテーマに抜粋し紹介しているスライドが素晴らしいです。
このスライドにある市町村名の変更例を題材に、代理キーに関するディスカッションがとても活発になりました。
以下、そのディスカッションからメモ。

■「自然キー」と「代理キー」
・ミックさんは、主キーは「自然キー」が良いと主張している。
・書籍「DBりファクタリング」では、主キーは「代理キー」でも良いと紹介されている。(P.159 「キー戦略の整理」参照)
データベース・リファクタリングデータベース・リファクタリング
(2008/03/26)
スコット W アンブラー、ピラモド・サダラージ 他

商品詳細を見る

・「自然キー」と「代理キー」、どちらの方が良い、ということは無い。これは宗教戦争。
・良い悪いではなく、好き嫌いの世界と捉えるべき。
・「論理設計」モードと「実装」モードでは、また別に考えないといけない。
・まず代理キーを使わずに頑張ってみるのはいいかも。
・代理キーは、現実世界には無いものなので、自然キーを探そうとするのは自然なこと。

■市町村の合併吸収の例 (スライドP.10以降)
・B市がQ市に変更になっても、市町村コードはB市のコードをQ市でも使いまわす必要がある。
 → じゃあキー設計をどうするか?
 → 「年度」という概念をカラムとして追加して複合キーとし、履歴管理すれば区別できるのでは?
 → 「西暦4桁」だと同年にもう一度合併吸収があったときに対応できないので、年月日の8桁で持つべき。

・「あるときに何が起こって、何が発生する」というのを表現する場合、時間をキーに追加することが多い。
20130523_sqlap_3.jpg
・市町村の合併と分離を考慮したモデルを最初に作っておかないといけない。
・これは、1個のテーブルで表そうとしている時点で無理。(上記の設計は完全ではない)
・3つの市が無くなって新たに「さいたま市」ができたような対等合併も考慮したりする必要がある。
・市区町村マスタがあればいい、という話ではない。


■表示順の制御
・表示順を主キーで制御したい、という場合に、主キーを変えたいという要件があるのでは?
→ いや、それは主キーにすべきではない。
・表示順ってのは実装のレイヤーなので、アプリ側で保証すべき仕組みの世界の話。
・自然キーだとキーの振り直しが発生することはある。例えば最近だと以下の例とか。

【例】年金機構から基礎年金番号の付番機能を剥奪せよ: http://takagi-hiromitsu.jp/diary/20130507.html
日本年金機構が、性同一性障害で性別変更した人を判別するため、基礎年金番号10桁のうち前半4桁に共通する固定番号として8500を割り当てた。
→ 世間にバレて炎上
→ 8500から5000に変更
→ さらに炎上

・表示順を制御するためのカラムをDBに持たせないといけないのは、そうしないとできない場合のみに限る。
 例えば、ある部署の平社員がとある別の部署の部長より権限が高く、表示上は上部に表示させたい、といった場合とか。

■1級と2級という表現(by @t_wada 氏)
・1級: 自然界にあって、人間が指を指せるもの。
・2級: システム都合上、無いといけないもの。(論理削除フラグとか)

→ 自然界に改編の理由があるなら、それは1級として扱う。

■複合キーと代理キー
・複合キーが面倒なのは、手を動かす段階(実装する段階)。
・論理設計の段階では、複合キーの方が良い。
・ORマッパーを使ってるので実装段階になると複合キーを避けたい、というのは実装都合である。
・モデルを読む側は複合キーの方がわかりやすい。でも実装になると複合キーはめんどくさい。


■前回のディスカッションの続き
前回、みなさんで付箋に書き出したもののタイムオーバーとなって扱えなかったネタを中心にディスカッションしました。
20130523_sqlap_2.jpg

■[3.2.4節] INNER JOINとUSING

・INNER JOINはWHERE句でも書けるが、そうすると等値結合と条件絞込みが混在してしまう。

・混在を避けるため、以下のように使い分けるべき。
 - WHERE句:条件の絞込み
 - INNER JOIN:等値結合

・USINGも同様、等値結合であることを明示するために使う。(WHEREでも書けるがUSINGの方が意図がハッキリする)
・INNER JOINの「INNER」は省略できる。
・ただし、LEFT OUTER JOINとかとの違いを明示するため、INNERを明記したほうが良い。

■[3.4節の最終行] 長い文字列の列にインデックスを付けるのは非効率な理由
・インデックスのデータ構造はKey&Valueではない。(線形構造ではない。木構造とか、何種類かある)
・B-Treeインデックスの場合、インデックスが一意に確定するまでノードのチェックに時間がかかる。
・対象データが大きいほど、B-Treeインデックスが大きくなるので、非効率となる。
・MySQLだと、先頭から桁数を指定してインデックス貼ることができるらしい。

■論理設計と物理設計の違い

・サイズの見積りやデータ型、桁数、文字コード、領域割り当ては論理設計でななく物理設計で行う。
・論理削除カラムや最終更新者カラムを検討するのも物理設計。
・TreeのNested Setとかを考え始めるのも物理設計。
・論理設計と物理設計とでテーブル構造とか関係性が変わることがある。
・スーパータイプとかサブタイプとかの設計は論理設計で実施するが、物理設計でなくしたりする。
 → その際にSTSとかでなくすらしい。(この話は5章のEAVで出てくるらしい)


★感想:
今回も大変有意義なお時間を過ごさせていただきました。
INNER JOINとWHEREの使い分けとか、私、今まで意識したことありませんでした。
んでもこの日の説明を聞いて「おぉ、なるほどなぁ」と感心しきり。今後意識してみようと思います。
あとB-Treeインデックスの話とか興味深かったですね。
インデックスの内部の仕組みまではほとんど理解できてないので、一度調べてみようと思います。

次回の4章「キーレスエントリー」、私がアジェンダのスライドを作ることになったので、早めに予習しよう。

皆様ありがとうございました~

-->