makopi23のブログ

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

SQLアンチパターン読書会 「インプリシットカラム」に参加しました

2014/4/25(金) SQLアンチパターン読書会 「インプリシットカラム」に参加してきました。

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

以下の書籍をターゲットとした読書会なのです。

SQLアンチパターンSQLアンチパターン
(2013/01/26)
Bill Karwin

商品詳細を見る


場所はいつもの湯島、株式会社アルティネットさんです。
いつも会場提供ありがとうございます。

参加者は13人かな。全員おなじみの方ばっかです。
この日は18章「インプリシットカラム」がターゲットでした。


■アジェンダ
今回は @setoazusa さんが発表担当でした。
Sqlアンチパターン読書会 インプリシットカラム from Hiroyuki Ohnaka



■ディスカッション
今回もディスカッションしたいネタをみんなで付箋に書き出しました。
20140425_sqlap1.jpg

以下、復習用の個人メモ。
---

■ 運用上がりのエンジニアとインプリシットカラム
  • オペレータとか運用担当者は、GUIのSQLコンソールでSELECT *を実行することに慣れている。
    • 最近のツールだと、Excelのようなスプレッドシートっぽく結果が表示される。
    • しかも、カラム数が多くてもGUIの右にスクロールすれば見れるし、レスポンスが遅ければ途中打ち切りもできる。
    • これに慣れた運用あがりのエンジニアさんは、アプリでもSELECT * としてしまう人が多いように感じる。
  • でも、SELECT * だと遅いということで、運用でも使わない派もある。
  • このへんは文化かもしれない。


■ RailsのActiveRecord
  • Rubyはメタプログラミングが強い。RailsのActiveRecordはSELECT発行時にSQLが2回走る。
  • 1回目はテーブル定義のメタデータを取得する。カラム名はメソッド名となり、メソッドを生やす。
  • 2回目に実際のデータをDBから取得する。
  • Rubyは動的型付け。DBにないデータもconcat関数やave関数を使えば作れるが、型がずれる。


■ カラム名と予約語
  • カラム名にcountと付けたらエラーになった・・・
  • あとは、classとかcontinueとかの予約語がカラム名に入っていて死んだことがある。
  • Cake PHPとかはSQLに予約語が入ってても、エスケープして発行してくれたりする。


■ Viewで逃げる
  • Alter Tableでカラムの追加や順番の入れ替えをした場合は、Viewを旧テーブル名で残す。
  • 表の構造を変更したのを知っているアプリは、新表にアクセスさせる。
  • 昔のアプリは旧表名のViewへアクセスさせる。
  • こうすることで、旧アプリがSELECT * でアクセスしていても、旧定義のViewに逃がすことで不整合を回避できる。


■ 仕様と実装の差異
  • JOINでカラムが重複してたときに、JDBCの仕様は先勝ちなのに、ドライバの実装によっては後勝ちだったりと異なる。
  • 大文字と小文字が混在している場合、SQL標準は大文字側に倒す仕様となっている。
  • ところが、PostgreSQLは小文字側に倒す仕様だし、MySQLは大文字と小文字の混在はそのまま扱う。
  • ちなみに昔、MySQLは擬似データベースとして呼ばれていた。仕様と異なるところ多いし。


■ 複数テーブル間でのカラム名の重複
  • 複数テーブルでカラム名は重複していても良い。
    • 今回の例だと、BooksテーブルとAuthorテーブルにtitleカラムがあるような設計はOK。
  • JOINを指定しつつSELECT * する場合は、ネームスペースが被っているんだからカラムが重複するのは当たり前である!
  • それはフレームワーク開発者が受け入れるしかない。
  • カラム名が重複してもSQLとしてはエラーにならず実行されてしまう点が手強い・・・
  • ORMはインプリシットカラムを自動で回避してくれる。
  • インプリシットカラムでハマるのは、ORMを使わずに手でコードを書く場合が多い。


■ カラム名による指定と、カラム番号による指定
  • SQLでカラム番号を指定してデータにアクセスするような場面はほとんど見ない。
  • アプリでは、カラム番号を指定してデータにアクセスすることはある。
  • JDBCはアクセス速度の都合上、カラム番号でデータを取得することを推奨している。名前解決が省略される分、高速。


■ PostgreSQL vs MySQL
(1) PostgreSQL
  • OSSのDBで、SQL標準の準拠率が最も高い。
  • Javaとの親和性が高い。
  • SQLは動的型付け言語であるが、PostgreSQLは強い型付け機構を持つ。
  • MySQLより高速。JoinはMySQLよりかなり速い。
  • 堅い運用に向く。疑わしきはエラーに倒す。
  • 透過フェイルオーバーが出来ない。クラスタ構成でサーバ側がコケるとロールバックできずに死ぬ・・・

(2) MySQL
  • だいぶ型付けが弱い。
  • 性善説で、曖昧なSQLをなんとか解釈して動作しようと頑張る・・・
  • 文字と数値が混在している場合は、文字っぽい箇所をDoubleにキャストするような変な挙動になる・・・
  • MySQL はスレッドモデルだが、PostgreSQLはプロセスモデル。
  • ちなみに初期のWindowsはCeeate Processが遅かった。プロセスモデルはプロセス生成のコストが重い。


■ SQLと正規表現
  • SELECT句にアスタリスクが使えるなら、SELECT句に正規表現が使えるようにしても良かったのでは?
  • いや、SQLに正規表現が導入されたのはだいぶ遅かった。
  • 正規表現がSQL標準に入ってから、SQLの文法が凄くデカくなって、パーサーを書くのが大変になった。
  • そんなで、SELECT句に正規表現は使えない。Drop table *とか出来たらヤバいよね・・・


■ DBのメタデータ
  • MySQL以外のDBMSは、メタデータをテーブルに保持している。
  • MySQLはメタデータを取得しようとすると、DB全体を舐め始める、なので監視してないと遅くなる。


■ JavadocのResultSetの説明は教育的?
  • JavadocのResultSetの説明に、列名が重複した場合について言及している。
  • java1.4は「列名を使用する場合、実際に目的の列を指すことを保証する方法がプログラマにはありません。」と書いてある。
  • Java1.4はツンな表現であるが、Java6は「一意にしたければAsを使え」と教育を始めている。


■ インプリシットカラムの解決策
  • インプリシットカラムはSQLの限界なので、他でカバーするしかない。「不要な列以外のすべての列」とか指定できないし。
  • 18.5節の「解決策」は、元々の目的であった「タイプ数を減らす」の解決になってない。
  • 列名を全部列挙したら、タイプ数って減らせない・・・。でも、これはSQLの限界なので、「そういうもの」として諦める。
  • SELECT句に列名をきちんと書かないといけないと、面倒くさいのでサボるようになり、本当に必要なカラムしか指定しなくなる。
  • これがパフォーマンスに好影響に傾く。(アスタリスクで全部取ってくるより、ネットワークの帯域とか減らせるし)



■終了後のお食事会
お食事会というか、今回はガチな飲み屋へ。
今回も木村さんのトークが炸裂して、みんなずっと大爆笑w








締めのお茶漬けにて。


これも皆でワロタw

★感想:
Select * の弊害について書いた章で、とてもシンプルです。
列の追加削除にアプリ側がついていけなくなり不整合を起こす問題と、パフォーマンスが悪化する問題と、弊害の観点は2つある点がポイントですかね。
とくに前者は、ズレに気づかずにアプリがたまたま動作しちゃったりすると悲惨です。。。
あと後者は、カラムの途中にLOB型があったりするとレスポンスが返ってこなかったり。。。
たぶん、参加者のみなさんもインプリシットカラムは一度は目にしたことあるんじゃないでしょうかね~
ということで、とても馴染みあるネタで付箋の数も多かったです。

今回で第Ⅲ部が終わり、次回の19章から第Ⅳ部に入ります。これも楽しみだ。
皆様、ありがとうございました。



■おまけ:過去の「SQLアンチパターン読書会」ブログ

1章:SQLアンチパターン読書会 「ジェイウォーク」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-65.html

2章:SQLアンチパターン読書会 「ナイーブツリー」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-70.html

3章:SQLアンチパターン読書会 「IDリクワイアド」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-73.html

3章:SQLアンチパターン読書会 「続・IDリクワイアド」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-77.html

4章;SQLアンチパターン読書会 「キーレスエントリー」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-84.html

5章:SQLアンチパターン読書会 「EAV(エンティティ・アトリビュート・バリュー)」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-90.html

6章:SQLアンチパターン読書会 「ポリモーフィック関連」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-94.html

7章:SQLアンチパターン読書会 「マルチカラムアトリビュート」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-97.html

8章:SQLアンチパターン読書会 「メタデータトリブル」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-105.html

9章:SQLアンチパターン読書会 「ラウンディングエラー」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-109.html

10章:SQLアンチパターン読書会 「サーティーワンフレーバー」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-115.html

11章:SQLアンチパターン読書会 「ファントムファイル」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-118.html

12章:SQLアンチパターン読書会 「インデックスショットガン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-121.html

13章:SQLアンチパターン読書会 「フィア・オブ・ジ・アンノウン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-128.html

14章:SQLアンチパターン読書会 「アンビギュアスグループ」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-130.html

15章:SQLアンチパターン読書会 「ランダムセレクション」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-133.html

16章:SQLアンチパターン読書会 「プアマンズ・サーチエンジン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-134.html

17章:SQLアンチパターン読書会 「スパゲッティクエリ」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-136.html

関連記事
スポンサーサイト

コメント

コメントの投稿


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

トラックバック

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

FC2Ad