fc2ブログ

makopi23のブログ

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

「SQLアンチパターン・レトロスペクティブ - データベース危篤患者の救出 -」に参加しました

2013/2/26(火) 「「SQLアンチパターン・レトロスペクティブ - データベース危篤患者の救出 -」に参加してきました。

DoorKeeper(告知サイト)
http://devlove.doorkeeper.jp/events/2775

Togetter
http://togetter.com/li/462950

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

商品詳細を見る


会場はIIJです。参加者は130名くらいでしょうか。あと大阪会場ともTV電話システムで繋がれました。

この講演、前々からとても楽しみにしてました。
データベースやSQLは、ソフトウェアエンジニアにとっては避けて通れない道だと思います。
なんせ、DBがないシステムなんてほとんど考えられないですからねー

SQLの知識はアプリ開発だけでなく、運用や保守でも要求されます。
かくいう私も、システム稼動直後からサーバルームに張り詰めて、ひたすら不具体対応のDBパッチ(更新系SQL)を本番DBに投げまくったりとかしたこともあります。。。
あと、お客さんから「~の条件に一致するデータを今すぐ取得してくれ」みたいに急にサーバルームで言われて、その場で検索SQLを組み立てて発行したりとかも、ずいぶんやりました。
あの時はSQLの本が手放せませんでしたなぁ。。。。懐かしい。

あと、IPA情報処理技術者試験のデータベーススペシャリストの資格も頑張って取りました。
合格したときは凄く嬉しかったなぁ。あの試験勉強でデータモデルの設計とか、かなり鍛えられた気がします。

しかも今回の登壇者は @t_wada さん!期待せずにはいられない。
ということで、以下メモ。


■講演資料はデブサミのがベースとなっていたようです。
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 from Takuto Wada


■最初に着席すると、「SQLアンチパターン」に書かれた25パターンの紹介資料が机に配布されていました。
 親切設計ですなー
20130226_devlove_1.jpg

20130226_devlove_2.jpg

■「SQLアンチパターン」は和田さんがオライリーで手掛ける2冊目。1年半くらいかかって監訳した。

■「SQLアンチパターン」に関するツイートはハッシュタグ #sqlap まで。

■二度目の増刷決定。まだ品薄。

■ビスマルクの有名な言葉「愚者は経験に学び、賢者は歴史に学ぶ。」

■上記は誤訳、端折られた訳なんじゃないか、と思っている。

■「他人の失敗を学ぶことで自分の失敗を回避する」というニュアンスの方が適切である。
 → 歴史を学ぶというよりは他人の失敗から学ぶ、ということ。
 → 誰かが失敗した、ということを共有することで自分の設計をより良くする。

■「SQLアンチパターン」は4つの部と25のパターンから成る。

■各アンチパターンの名称は、趣味でカタカナにした。
 → 目立つ & 共有しやすいように。かなり中二病っぽくワザとしている。


Ⅰ部「データベース論理設計のアンチパターン」

■1章「ジェイウォーク(信号無視)」

・ある製品に人が1対1になっていたが、仕様変更で1対多になった。
 → 多の情報を格納するカラムの型をvarcharにして、カンマ区切りで入れちゃおう。
 → ダメな典型。。。

・交差テーブルを避ける
 → ジェイウォーク

■2章「ナイーブツリー」

・ツリー構造を設計する場合に、一番素朴に設計すると、親IDを持ってぐるぐる参照構造を持たせる。
 → 数階層ならいいが、どれだけ深くなるか分からない場合は、設計に限界が来る。

■3章「IDリクワイアド」

・主キーをとりあえずIDにしよう
・連番にしょう
・Railsとかに乗っていると自然とこうなっている。
・何でもID振っちゃうパターン

■4章「キーレスエントリ」

・外部キーを定義せずに、アプリ側で整合性を取ろうとするパターン
・いろんな恐れにより外部キーを持たせずアプリで頑張るパターン

■5章「EAV(エンティティ・アトリビュート・バリュー)」
・ものすごく動的な項目を作りたい
・外部キー 値 名前

■6章「ポリモーフィック関連」

・あるエンティティを複数のものに関連づける
・結局フォーリンキーをつけれなくなって、アプリで頑張らざるを得なくなる

■7章「マルチカラムアトリビュート(複数列属性)」

・ジェイウォークでカラム区切りダメとなった場合によく陥るパターン
・テーブルに出してフォーリンキーを貼りましょう

■8章「メタデータトリプル(メタデータ大増殖)」
・年でカラムやテーブルを分ける
 → 年が変わるとバグるシステムになる
・メタ(例:年)が増えることによってテーブルが増えるパターン

■和田さんもジェイウォーク以外はハマッたことがある。
 → EAVにハマッたのがこの本を訳そうと思ったキッカケ


Ⅱ部「データベース物理設計のアンチパターン」

■9章「ラウンディングエラー(丸め誤差)」

・不動小数点を使って誤差が出る
・少数を表すために不動小数点を使うのがアンチパターン
・DECIMALやNUMBERを使うべき

■10章「サーティンワンフレーバー(31のフレーバー)」
・特定の値のみを取り得るパターンにしたい
 → 列定義で限定してしまうのがダメ
・この値しか入れられないという制約は付けれるが、どの値を入れられるかは設定を追わないとわからなくなる。

■11章「ファントムファイル(幻のファイル)」

・画像とか動画とか大きいバイナリを扱うとき、パスのみDBにいれて、本体は外に置くことをよくやる。
 → ファイルは外に置くもんだ、と考えるのがアンチパターン
・DBのロールバックとかで考慮されなくなってしまう。(DBはロールバックされても外のファイルは残ったまま)
・LOBに入れろ、というのが著者の主張。でもそれはないでしょ、という意見も多い。

■12章「インデックスショットガン(闇雲インデックス)」

・インデックスを貼りまくる
・測定とかテストとかせずに、めくらめっぽうにインデックスを貼る


Ⅲ部「クエリのアンチパターン」

■13章「フィア・オブ・ジ・アンノウン(恐怖のunknown)」
・NULLは扱いが難しい。TRUE/FALSEにプログラマは慣れているが、DBはそうではない。
 → NULLを嫌って-1とかにする。
・ちなみに著者はNULL容認派。

■14章「アンビギュアスグループ(曖昧なグループ)」
・製品ごとの最新のバグを取ろうとして、MAX関数でバグIDを取ろうととする
 → DBMS依存で必ずしも想定の値が返ってこないことがある

■15章「ランダムセレクション」
・和田さんはやったことない
・バグの数が増えれば増えるほどすごく遅くなる

■16章「プアマンズ・サーチエンジン(貧者のサーチエンジン)」
・全文検索をLIKEで頑張る。
 → 量が増えるほどとんでもないことになる
・DBMSの全文検索機能を使うべき

■17章「スパゲッティクエリ」
・複数のことを一発でやろうとする
・プログラムの世界ではダメだとわかっているが、SQLだとやろうとする傾向がある
 → シンプルなクエリを複数に分けたりして避けるべき。

■18章「インプリシットカラム(暗黙の列)」
・ワイルドカードをアプリケーションコードに入れていると、列の追加削除にアプリがついてこなくなる
・列名をちゃんと書きましょう
・コンソールでSQL打ち込む場合はいいが、アプリとしてやってしまうのはダメ


Ⅳ部「アプリケーション開発のアンチパターン」

■19章「リーダブルパスワード(読み取り可能パスワード)」

・パスワードを平文でDBに入れる。最近もまだこんなことやってることがある
 → ソートつきのハッシュを使いましょう

■20章「SQLインジェクション」

・エスケープしましょうというより、プリペアドステートメント使いましょう
・それでも上手くいかない場合にどうすべきか、本に書いてある

■21章「シュードキー・ニートフリーク(擬似キー潔癖症)」
・欠番がある
 → 欠番があると埋めようとしてしまう。
・欠番を埋めてもろくなことない。
 → じゃあ、どうしますか、が本にかかれている

■22章「シー・ノー・エビル(臭いものに蓋)」
・例外のハンドリングをしないのはダメ
・落ちるとどこが悪かったのかわからなくなる

■23章「ディプロマティック・イミュニティ(外交特権)」

・SQLを特別扱いしてドキュメンテーションとかバージョン管理とかテスティングとかしないのはダメ。
・データベースの世界も従うべき

■24章「マジックビーンズ(魔法の豆)」
・アクティブレコードを降るに使うと構造が丸見えになってしまう。依存性のグラフが複雑になりすぎる

■25章「砂の城」

・想定不足のパターン。奥野さんの書き下ろし


■アンチパターンとは、べからず集、あるある集だけではない

■この形式を覚えておいてほしい。25のパターンは全部こうなっている
 0.名前がついている
 1.目的
 2.アンチパターン
 3.アンチパターンの見つけ方
 4.アンチパターンを使ってもいい状況が書かれている
 5.解決策までかかれている

■0.名前がついている
・アンチパターン名はなぜカタカナ?
 → 諸橋さん曰く「目立つようにしたい」
・「素朴な木」だと会話に混ざってしまう。
 → 「ナイーブツリー」とカタカナにした。
・議論のひとつのポインタにパターン名がなってほしい
・パターン名でいきいきとした議論ができるようにしたかった
・必殺技の名前のようにしたい
・名前だけで何がマズいか、とかを共有できるようにしたかった

■2.アンチパターン 
 = 良かれと思って裏目にでてしまう

・例:ナイーブツリー(素朴な木)
 階層が深くなればなるほどJOINを増やさなければならない
 → 素朴すぎるがゆえにアンチパターンになる

■4.アンチパターンを使ってもいい状況が書かれている
 → この本のフェアなところは、アンチパターンを使ってもいい場合に言及していること。

・例:ナイーブツリー(素朴な木)
 共通テーブル式という機能を使って再帰クエリを書けるのであれば親IDをもたせてもいい。
 特定のDBMSならOKという制限を設けている

・アンチパターンでも、ある状況では正しい、ある状況では間違った判断、とコンテキストや制約で変わる。
 → ここをこの本は理解している
 

■5.解決策までかかれている
・ナイーブツリーの解決策として、階層をスラッシュ区切りで表現する代替ツリーモデルを使う
・解決策も得意不得意がある。1つ1つ論じられている

■おわりに
・この本は、他の人の失敗が結晶化されている。
・このままだとやばい、と嗅覚がはたらくように。
・きちんと名前つけて議論しましょう


グループダイアログ1「SQLアンチパターン・レトロスペクティブ」

SQLアンチパターンのカタログを片手に、25の落とし穴それぞれについての失敗談を思い起こし話しあう時間です。
約1時間で、以下のことを行いました。
・各自の失敗談について約4名のグループ毎に話す。
・グループでどのアンチパターンを話すか決める
・カタログの解決策を横目で見つつ、どうすればよかったのかを全員で話し合ってみる

ウチのグループは4章「キーレスエントリ(外部キー嫌い)」について主に話し合いました。
大体以下のような意見が出ました。

・外部キーを貼ると、テストデータのinsertやdelete時に参照制約がかかりまくって上手くinsertやdeleteできないことがある。
・外部キーをDBに貼らないなら、アプリ側で整合性を制御しなければならなくなる。
・DBは最後の砦。アプリ側で必ず対策してくれるとは限らない。

途中、傍を通りがかった和田さんからも、キーレスエントリに関するコメントを戴けました。

・昔はテストデータのローディングに失敗するからやりたくなかった。
・今では、テスト毎にテストデータを作ることができるようになった。

次に、各グループで議論したことを共有する時間が設けられました。

■失敗談1「ジェイウォークとEVAの組み合わせ」
・テーブルにJSONをいれる
 → テーブルに何が入っているか誰もわからなくなった

■EAVについて。
・本当にバリエーションがわからないからEAVにせざるを得ない状況なのか、考えること重要。
・3つくらいバリエーションが出ると、めんどくさいから全部いれちゃえばいいや、となる。
・そうなるとDBMSの良さが失われる。

■失敗談2:オレオレ図
・ER図じゃなくて四角と線で結ばれているオレオレ図のような仕様書があった。


グループダイアログ2「26個目の落とし穴を探せ」

SQLアンチパターンにはまだ無い、26番目のアンチパターンとは何か?をグループで考えることをやりました。
具体的には以下のことをやります。

・こーゆうのがあった、というのをグループで共有する。
・どーすれば良かったのか。
・アンチパターンの見つけ方はどうだったか
・どーいう状況が弊害が出たか
・アンチパターンの名前まで考えて付けてみる


■「形無しの型」
・カラムのデータ型を守らない

■「レインボークエリ(通天閣クエリ)」
・SQLはいろんな書き方がある。例えば、副問い合わせの代わりにUNION JOINとか。


■トリガーに関するアンチパターン1
・DBにはカスケードとかトリガーを仕掛けることができる。
 → DBに隠れた挙動というものが出てくる。
 → それが中性脂肪のように溜まっていく。
 → DBを扱っているだけなのに、裏でなにかが動いている、というような状況に陥る。

■トリガーに関するアンチパターン2「忍者屋敷」
・トリガーが連鎖的に反応し、あるトリガーの結果が他のトリガーに引っかかる。

■DBのドメイン定義が重要。トリガーは止むを得ない場合のみ使う。

■カスケードデリートとかカスケードアップデートというのは、和田さん(父)は設計したことがない。

■26個目のアンチパターンについて是非ハッシュタグ #sqlap #devlove でツイートしてほしい。

■みなさん、自由な設計で考えがちでは。
 → 論理設計段階でかっちりした構造がもっとできるじゃないか。by 和田さん(父)

■大事なのはバランスを取ること。Strictのレベルを自分として持っていくのが大事。


★感想:

大変興味深い内容で、凄く引き込まれた2時間でした。
最初「SQLアンチパターン」というタイトル名を見たとき、「あぁ、インデックスが利かないSELECT文の書き方はダメ」とかのレベルがたくさん書いてあるんだろなー、と思ってました。
でもこの講演を聴いて、そんなレベルではなくDBの論理設計、物理設計から考察している点にビビッた。
DMLだけじゃなく、DDLも考慮しているんだ、むしろそっちの方が多そうだ、という感触でした。

ということで、コレは良さそう!と思い、帰り際に会場でSQLアンチパターンの書籍を買いました。
どっかでこの書籍の勉強会とか読書会あるといいのにな~

最後に、講演者の和田さん親子、papandaさん、スタッフさん、会場提供者さん、ありがとうございました。
関連記事

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://makopi23.blog.fc2.com/tb.php/54-8bcf35c4
この記事にトラックバックする(FC2ブログユーザー)

-->