裏でやっていた #awssummit Day2 とギリギリまで天秤にかけていたのですが、あまりにも#awssummit の Day1 の印象が悪かったので、こちらに参加することにしました。
富士ソフトアキバビル 1F の案内が
「PB エンジニアのための勉強会」になっていたw
開催概要:
- DBエンジニアのための技術勉強会
- 主催: エンバカデロ・テクノロジーズ
- 日程: 2013年6月6日(木) 13:30〜16:15 (13:15 受付開始)
- 会場: 富士ソフト アキバプラザ 6階 セミナールーム1
- 参加費: 無料(事前登録制)
アジェンダは以下のようになっていました。
アジェンダ:
- 13:30〜14:30 『SQLアンチパターン』
- 14:30〜14:45 休憩
- 14:45〜15:45 『やはりデータ設計は大切です』
- 15:45〜16:15 Q&A
では、今日も所感から。
1. SQL アンチパターンは買い!
- 25 のアンチパターンは、実際にわたしが DBA としてそれはやったらあかんとアプリケーションエンジニアと格闘したものとモロカブリのものが多くてビックリしました。わたしの場合、時間等の制約の結果、相手を結局説得できず、その後ひどい目にあったことがあったのですが、この本をお互いに読んでいたら、アンチパターンを共通理解としてもつことができ、そういったことを減らすことができていただろうなぁと思いながら聞いていました。
- 個人的にはナイーブツリーとエンティティ・アトリビュート・バリューを深堀りしてみたいと思っていますが、 SQL アンチパターン本をまだ買って読んでなかったのでこれから買おうと思います。
2.
エンバガデロテクノロジーズエンバカデロ・テクノロジーズさんの勉強会には内容次第でこれからも参加したい
- もともとわたしは DB エンジニアなのと特にデータモデリングには深い関心があるため、 ER Studio のベンダーである
エンバガデロテクノロジーズエンバカデロ・テクノロジーズさんの主催する勉強会は興味のあるものが多そうな気がします。これからも内容次第で参加させていただこうと思います。今日は有意義な勉強会の機会をありがとうございました。3. 藤原紀章さんのべしゃりが面白いのはよくわかったw
では、以降より、わたしがとってきたノートになります。
はじめに
- 勉強会の背景の説明、
エンバガデロテクノロジーズエンバカデロ・テクノロジーズの紹介。ER studio のベンダーというとわかりやすいかも。会社が提供するシステムに近しい内容で SQL アンチパターンについて話してもらおうということになった。継続して、こういった勉強会を開催していく予定なので、奮って参加してほしいとのこと。
13:30〜14:30 『SQLアンチパターン』
概要:
デブサミ2013のアワードを受賞した、和田卓人氏が話題のSQLアンチパターンを分かりやすく解説。DBの設計・開発には、様々な場面で陥りやすい失敗(アンチパターン)があります。データベース論理設計、データベース物理設計、クエリの記述、アプリケーション開発という4つのカテゴリに分け、それぞれの分野におけるアンチパターンを紹介し、失敗を避けるためのより良い方法を解説します。
タワーズ・クエスト株式会社 取締役社長 和田卓人氏
➤ 自己紹介
- id: t-wada
- @t_wada
- github:twada
エンバガデロテクノロジーズエンバカデロ・テクノロジーズの勉強会のハッシュタグは #dcampjp
➤ SQLアンチパターンという本に関する話題
- スピーカーが監訳者、親子で監訳者
- 本のハッシュタグが #sqlap
- この本に対する質問などをこのハッシュタグをつけてつぶやこう
➤ ビスマルクの言葉
- 愚者は経験に学び、賢者は歴史に学ぶ。
- 実は、いろいろ端折られている。
- では本当はどんなことをいっていたのか?
- 他人の失敗を学ぶことで自分の失敗を回避することを好む
- SQLアンチパターンはその考え方にもとづいて書かれている本の主題
➤ アンチパターンとは?
- たんなるベカラズ集、あるある集だけではない
- 本書のアンチパターンの構成、すべての章がこの構成になっている
- 0. 名前(名前重要)
- 1. 目的
- 2. アンチパターン
- 3. アンチパターンの見つけ方
- 4. アンチパターンを用いても良い場合
- 5. 解決策
- 名付けの例
- 例:ナイーブツリー(素朴な木) #第二章より
- なぜカタカナ?!
- パターン名が英語そのままカタカナ表記であるのは、目次を見てビックリするポイント
- ただ、チーム内で相談するときに目立つ名前がついているのはむしろありがたいですし、何よりなんかカッコよくておもしろかった
- SQLアンチパターン -- 苦い経験を思い出させる良書 - moroの日記 より
- ナイーブツリーとはどんなアンチパターンなのか?
- 目的:階層構造を格納し、クエリを実行する
- RDBと階層構造は伝統的に相性が悪いので、うわあと思うはず
- アンチパターンは?
- 問題の解決を意図しながらも、しばしば他の問題を発生させてしまうもの
- よかれと思って裏目にでる
- ナイーブツリーのアンチパターン:常に親のみに依存する
- parent_id が入っている
- どんどん LEFT OUTER JOIN で積んでいかないといけなくなる
- 素朴すぎるゆえにアンチパターン
- アンチパターンには見つけるためのパターンがある
- 直面している問題の種類や、メンバー間の何気ない言葉がヒントになる
- 例えば
このツリーでは、深さを何階層までサポートすればいい?みたいな会話がされている
- そしてアンチパターンを用いてもいい場合もある
- 共通テーブル式をつかって再帰クエリをかける場合
- 現状、 MySQL ではまだサポートしてないことだが…
- この本のいいところは、べからず集ではなくパターン本だからコンテキストや制約が異なれば導かれる解法も違う
- 最後に解決策
- 解決策(1):代替ツリーモデルを使用する
- 経路列挙: materialized path
- 解決策(2):入れ子集合 NestedSet
- 集合の中に集合をもたせるトリッキーな解決策
- 解決策(3):閉包テーブル Closure Table
- あるノードとあるノードの関係を別テーブルに格納する
- 解決策(1):代替ツリーモデルを使用する
-
- 解決策の比較表もある
- 状況によって、この星取表から解決策を選ぶ
- 解決策の比較表もある
➤ 本書のダイジェスト
- アンチパターンと解決策をすべて紹介
- 4つの部、25パターン
- 4つの部
- 論理設計
- 物理設計
- クエリ
- アプリケーション
論理設計の部
Pattern(1) ジェインクウォーク(信号無視)
- カンマ区切りで多対多関連を格納してしまう
- 解決策は交差テーブルを作成すること
- 関係間がわかりやすい名称をつけることがポイント
Pattern(2) ナイーブツリー
- 上述されたので割愛
Pattern(3) IDリクワイアド(とりあえず id)
- 考えなしにとりあえず主キーを id という名前でつけてしまう
- こういう設計が悪いわけではない、考えた結果の id ならそれでよし
- 明快な回答もない
- わかりやすい列名をつける(同じ名前なら using が使える)
- 規約に縛られない自然キーと複合キー
Pattern(4) キーレスエントリー(外部キー嫌い)
- 外部キーを定義せず、整合性をアプリで保つ→アプリ以外からゴミデータが入る
- 解決法:きちんと外部キーを定義する
Pattern(5) EAV(エンティティ・アトリビュート・バリュー)
- 動的な項目を格納したい
- たとえば、アンケートフォームをお客さんが自由に作りたいと思っていたとする
- 結果、 Issue と IssueAttributes のようなテーブルをつくってしまう
- 解決策:エンタープライズアプリケーションアーキテクターパターン、読むべしw
- 一行じゃ説明できぬ、と
- 継承構造をどうにかテーブルに格納しようとするパターン
- シングルテーブル継承
- 具象テーブル継承
- クラステーブル継承
- 継承構造をどうにかテーブルに格納しようとするパターン
- 動的部分だけは XML とか JSON にいれましょうというパターン
-
- シリアライズ LOB
※ただその半構造データも検証できるようにしておくとあとあと便利
- シリアライズ LOB
-
Pattern(7) ポリモーフィック関連
- テーブル名が行にはいってきてしまうようなパターン
- 解決策:関連を単純化する
Pattern(8) マルチカラムアトリビュート
- 空いてる列に値が入る
- たとえば tag
- 解決策は王道中の王道、他テーブルに切り出す(従属テーブルを作成する)
Pattern(9) メタデータトリブル(メタデータ大増殖)
- 年が変わるごとにテーブルや列を追加している
- 年々パフォーマンスが劣化しないようにしたためなんだが
- データがメタデータの中に紛れ込んでいることが問題だってこと
- 解決策は水平パーティショニング(SQL標準の中には解決策はないけれどもという感じ)
物理設計の部
Pattern(10) ラウンディングエラー
- 少数値を表すために浮動小数点を使ってしまったため、丸め誤差が発生してしまった
- 解決策:NUMERIC データ型を使用する
Pattern(11) 31フレーバー
- 許可する値を列定義で指定する→アプリから許可値を取得できない
- 解決策:別テーブルにステータスを管理し、外部キーで整合性を保証する
Pattern(12) ファントムファイル(幻のファイル)
- 物理ファイルの使用を必要だと思い込んでしまったパターン
- ファイルはDBの外にある
- 解決策:必要に応じてBLOB型を使う
- 整合性、トランザクション、ロック、権限管理がメリットになる
- ただし、バックアップのサイズなどのデメリットもあるので注意が必要
Pattern(13) インデックスショットガン(闇雲インデックス)
- 闇雲にインデックスを定義する
- 解決策:MENTOR の原則にもとづいえ効果的なインデックス管理を行う
MENTOR は以下の頭文字をとって MENTOR- Measure
- Explain
- Nominate
- Test
- Optimize
- Rebuild
クエリの部
Pattern(14) フィア・オブ・ジ・アンノウン
- NULL を嫌って NULL 代わりに値を設定しておかしなことに
- 解決策:本書の著者は NULL 容認派なので、 NULL を一意な値として使っている。漢が怒りそうだ…
- IS DISTINCT FROM ならプリペアドステートメントにも使える
Pattern(15) アンビギュアスグループ(曖昧なグループ)
- 最新のBugidがとれるとはかぎらないというアンチパターン
- 王道はない解決策
- 集合関数に対してきちんとした理解が必要
Pattern(16) ランダムセレクション
- 非決定性をもつ式によってソートを行なってしまう
- order by rand limit 1; みたいな
- 解決策:特定の順番に依存しないようにする
Pattern(17) プアマンズ・サーチエンジン
- あいまい検索にパターンマッチ述語を使用してしまう
- like "%one%"
- 解決策:適切なツールを使用する
- ベンダー拡張の全文検索機能 Solr とか
Pattern(18) スパゲッティクエリ
- 複雑な問題をひとつのクエリで解決しようとしてしまう
- 小さな単位に分割するのがいいのはプログラムと一緒
- マッチョなクエリにいいことなし
Pattern(19) インプリシットカラム
- タイプ数を減らしたい欲望に負ける
- select * from hoge と買いちゃうこと
- 解決策:列名ちゃんと書けよ、と
- Fail first の原則にきちんとのりきること
- これによってパフォーマンスもあがることになる副次効果も。
アプリケーションの部
Pattern(20) リーダブルパスワード(読み取り可能パスワード)
- パスワードを平文でDBに格納してしまう、まさにエクスコムグローバルのバカがやったこと
- 解決策:ソルトをつけてパスワードハッシュを格納する、もう当たり前の当たり前
Pattern(21) SQLインジェクション
- 未検証の入力をクエリにつなげて実行してしまう、これもまさにエクスコムグローバルのバカがやったこと
- 解決策:誰も信用してはいけない
- 外部からの入力は絶対に信用してはいけない
- あえていうなら、第一にプリペアドステートメントをつかうべし
Pattern(22) シュードキー・ニートフリーク
- 気になるので欠番の隙間を埋めてしまう
- 自動採番の欠番を人間が埋めようとしてしまうことで、延々と作業連鎖が発生してしまう
- 解決策:擬似キーの欠番はうめるべからず
Pattern(23) シー・ノー・エビル
- 俺様、ぜったい間違わない。戻り値や例外をチェックしない
- 解決策:ちぇっくしろよ
Pattern(24) ディプロマティック・イミュニティ
− 文章化
− バージョン管理
− テスティング
-
- DB管理者もちゃんとやれ!
- Rails 以降 migration というのができるようになっている
Pattern(25) マジックビーンズ
- モデルがアクティブレコードそのものなので、ドメインロジックを迂回できる
- 解決策:モデルがアクティブレコードを「持つ」ようにする
Pattern(25+1) 砂の城(奥野さん描きおろし)
- 様々な想定不足
- 解決策:考えて備えるべし
- Benchmark
- テスト環境
- 例外処理
- バックアップ
- 高可用性などなどなど
14:45〜15:45 『やはりデータ設計は大切です』
概要:
これまで金融機関をはじめとした、数多くの開発プロジェクトにPM、コンサルタントとして携わり、DOAの専門家でもある藤原紀章氏が、DB開発の視点から見た、プロジェクトをより良く推進する体制やプロジェクトの進め方のノウハウを説明させていただきます。プロジェクトを進める上で役立つ実践的なノウハウが満載です。
株式会社ファイナンシャルブレインシステムズ ソリューション第一本部 開発四部 課長 藤原紀章氏
➤ 10年、データ設計やってきて、やはりデータ設計は大切です
- わたしとデータ設計
- DFD 自体は単にシステムを写しとったものにすぎないので、直接的な成果として認められ難いからである
- データ中心システム設計より
- ここから、データ設計しなかったら、仕事した気になるなぁと解釈したw
- おもしろい解釈w
➤ 情報システムの付加価値とデータ設計
- 事実>情報の生産>記録>蓄積>編集>情報の再利用>価値の実現
- 事実と価値の実現の間をむすぶプロセスの重要性
- 情報システムが付加価値を生む仕組み
- 情報システムによる価値実現は、データ及びプロセス設計の巧拙によるといえる。
- 価値実現のイネーブラー
- 情報システムの価値実現過程を情報連鎖という
- その場合、蓄積と再利用が生み出す付加価値を左右する
- 連鎖をつなぐ蓄積
- 利用者にサービスを提供する再利用
➤ データ設計の設計目標
- 業務忠実、忠実な理解:業務目的、存在意義を含む
- データ品質:質とは、業務忠実を検証しやすいこと
- 業務忠実を考察する
- 業務とは DOA の観点からすればデータの生産のことである
- マスタ、イベント、集約情報
- 事業・データ生産モデルの交差kつ
- 事業の流れに沿っている
- 単純わかりやすい
- 問題が具体化しやすい:事業課題をデータ項目まで構造化できる
- あるべき姿を提供できる:具体化してこそ、理想は達成できる。そこまでデータ項目を精査する
- まずはマスタをつくって、イベント、集約情報と展開していく
- 課題をデータ項目に具体化していく
- 業務忠実ってレビューできるの?(事業・データ生産モデルから算出されるデータ品質基準)
- マスタ
- 範囲:何をマスタにするか?
- 粒度:1レコードが示す範囲は適切か?
- イベント
- 完全:正しく事実を捉えているか?
- 存在:その場面で発生して良いか?
- 集計データ
- 適合:意思決定に資するか?
- 正確:偏向がない、再現性があるか?
- マスタ
➤ データモデルについての概説
- データモデルの一般構造
- 椿のエンティティ類型
- http://www.seshop.com/product/detail/6334/ のへんに書いてありそう
- エンティティにもタイプがある
- タイプリソース(ライフサイクルを持たない)、オカレントリソース(ライフライクルをもつ)、イベント、要約、在庫、断面
- 椿のエンティティ類型の功績
- データ派生順序を提示した
- タイプリソース、オカレンスリソース、要約、イベント、断面、在庫
- タイプリソースの発見
- ビジネスルールを可視化した
- データ派生順序を提示した
参考になりそう:椿正明ブログ/ウェブリブログ
➤ データ設計の実際
- 要件定義工程、そのポイント
- 現行分析はかならず行う
- データ設計を行う
- 凝った業務フローはつくらない
- 用語の意味定義を行う
- 作業展開例
- IPF:インフォメーション・プロセス・フロー(椿・2005)
- 部分図とは?:1つの業務画面、帳票のデータ構造を図示したもの
- 統合図とは?:システム化範囲すべてのデータ構造を図示したもの
- 特徴:
- 処理を書かない
- 用紙は横書きがおすすめ
- 無駄な分析をしなくていい
- 客観的で標準化が可能
- データ設計は KJ 法と同じ手法で行う
- モデル化して統合していく
- 設計工程のポイント
- 意味論的ドメイン設計を行う
- データ構造に基づく部品化を行う
- 意味論的ドメイン設計には意味がある
- ドメイン設計の例
- 区分、分類、コード、シーケンス番号、数値、文字列
- データ構造は情報システムの部品の集合
- 部品化に適した構造をしている
➤ 総括
- データ設計は情報システムがユーザにもたらす付加価値を左右
- なので最も関心をおかないといけない
- 要件定義工程では定義工程では、要求事項の具体化と、実現可能性の両者を具現化する
- 設計工程では、用語の意味とデータ構造に沿った部品化を行うことで、そこに示された要求事項を正確に設計することが可能になる
- 統合と総合
- 要素技術を提供するベンダーと価値を実現するために要素技術を「統合」するユーザの構図はこの 40 年間変化していない。
- 情報システムは「統合」によりユーザの業務に付加価値をもたらす
- 要素技術を集めただけの状態、すなわち「総合」では付加価値を提供したことにはならない。
15:45〜16:15 Q&A
Q1. SQL のアンチパターン、 ID リクワイア
- 和田さん:
- なぜダメなのか?
- 賛否両論なんだが、論旨が不明瞭だから
- その id だけをみてなんだかわからない
- DB 全体をみて、名前が一貫性があったほうがいい
- id という主キーがないといけないという思い込みがこわい
- id というカラムがいかんというより思考停止がいかんということに警鐘をならしている
- OR Mapper によって考えなくてよくなってしまっているため
Q2. ID リクワイアについてふたたび
- 和田さん:
- テーブル名をカラムに含めるのはどうなんだという話もあるが?
(きちんと聞き取れなかった)
- テーブル名をカラムに含めるのはどうなんだという話もあるが?
Q3. データ設計を KJ 法と同じ発想で。 KJ 法以外ではあるか?
- 藤原さん:
- KJ 法ではっきりできると言ったのは椿さんだけ
- スピーカーはそれしか知らない
- ボトムアップでやってもいいとおもうが、それでやると大抵失敗する。
Q4. チーム内共有について
- 和田さん:
- アンチパターンは共有の仕組み、ダメなことに名前がついてる効果は大きい。ダメなことに名前がついてさえいれば、あとは自分で調べることだってできる。
- 藤原さん:
- 知識の伝播はどうしているのか?
- IPF の読み方を教える。部分図をかけるようにしてもらう。
- 抽象化する技術は、統合するセンスが必要。センスは教えて身につくことではない。
- 自分はそれをフルートを吹くこと、絵を描くことでトレーニングしている。
Q5. プロジェクトにおける論理設計担当の位置づけをどうしているのか?
- 藤原さん:
- 担当を置くこと自体が間違い
- プロジェクトに関わる人間すべてがデータモデルを行う
- 担当を置くこと自体が間違い
Q6. 砂の城
- 実際、想定不足への対応は身に痛いものがある。それへの対応でうまくいっていることがあれば?
- @nippondanji に聞くのがいいだろう。
- 痛い目をみたことをどうやったら形式知化できるのかということをつきつめるしかない
- 想定不足は起こりうること。
- 起こったときにどうやって、次に繋げるかが大事。
- そういう意味では、チェックポイント化することがポイントなのではないか。
- 論理設計でうまくいき、物理設計でこけるような場合は、そういうチェックポイントがうまくつくれていないのではないか
- 社内のナレッジベースに失敗例が社内でどれだけ共通フォーマットで蓄積されているかが大事なのではないか(ブログみたいなのではなく)
以上が、この勉強会のノートでした。
参考:
- DBエンジニアのための技術勉強会 - ライブ中継
- SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版) #2013-06-10 追記