「達人に学ぶSQL徹底指南書」を読んだ

「達人に学ぶSQL徹底指南書(第1版)」を読んだ。

達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)

達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)

最近第2版が出たらしい。

どんな本

SQLにある程度親しんでいる人が、もう一段階進みたいときに読めそうな本。
大きく2部に分かれていて、
第1部はCASE式、NULL、自己結合、HAVINGなどの使い方や、効率的なSQLの書き方やお作法について書かれている。
第2部はリレーショナルデータベース・SQLの歴史や理論、概念的な話が書かれている。アカデミックな感じ。

目次

第1部 魔法のSQL

1-1 CASE式のススメ
 ~SQLで条件分岐を表現する
1-2 自己結合の使い方
 ~集合指向言語としてのSQL
1-3 3値論理とNULL
 ~SQLの甘い罠
1-4 HAVING句の力
 ~意外な名脇役
1-5 外部結合の使い方
 ~SQLの弱点:その傾向と対策
1-6 相関サブクエリで行と行を比較する
 ~SQLで行間比較
1-7 SQLで集合演算
 ~SQLと集合論
1-8 EXISTS述語の使い方
 ~SQLの中の述語論理
1-9 SQLで数列を扱う
 ~述語論理を使いこなそう
1-10 帰ってきたHAVING句
 ~もう脇役とは言わせない!
1-11 SQLを速くするぞ
 ~お手軽パフォーマンス・チューニング
1-12 SQLプログラミング作法
 ~SQLコーディング・スタイルの確立に向けて

第2部 リレーショナル・データベースの世界

2-1 リレーショナル・データベースの歴史
 ~1969年―全てはここから始まった
2-2 なぜ“関係”モデルという名前なの?
 ~なぜ“表”モデルという名前ではないのか
2-3 関係に始まり関係に終わる
 ~閉じた世界の幸せについて
2-4 アドレス、この巨大な怪物
 ~なぜリレーショナル・データベースにはポインタがないのか?
2-5 GROUP BYとPARTITION BY
 ~類は友を呼ぶ
2-6 手続き型から宣言型・集合指向へ頭を切り替える7箇条
 ~円を描く
2-7 SQLと再帰集合
 ~SQLと集合論の間
2-8 神のいない論理
 ~論理学の歴史をちょっとだけ
2-9 NULL撲滅委員会
 ~万国のDBエンジニア、団結せよ!
2-10 SQLにおける存在の階層
 ~厳しき格差社会

第3部 付録

3-1 演習問題の解答
3-2 参考文献

特徴的なのは単にこう書けばいい、という内容ではなく、全体的にSQLの根本をなす集合論の話から始まり、そのあとSQLでこう書く、というような話になっているところ。
なのでわかりやすいとも言えるが、すべて理解して読もうとすると結構難しい。

1部を読んでおくと確実にSQLに対する理解やクエリを書く力は上がる。
演習問題もあるのでちゃんと練習できる。けど結構難しい。そしてmysqlでやるのは向いてない。 (EXCEPTとかが非対応なので)

ちなみに最近第2版が出て、こちらはwindow関数や最近のビッグデータを対象にした書き方の加筆がされているらしい。

なぜ読んだか

以前kindle版が割引されていて積読になっていたから。
業務では以前はwebアプリのサーバーサイド、今はデータ可視化のインフラ整備やBIツールの利用など、SQLを書く機会がそれなりに多く、もうちょっといい感じにSQLを書きたいと思っていたので読んでみた。

メモ

  • UNIONやINSPECTを使うと重複行は排除される。そのためソートが内部的には行われるが、ALLをつけるとソートが行われない。重複を気にしない場合や重複がない場合はALLをつけておくとパフォーマンスが向上する。
  • 全称化(「すべての行について〜」のようなやつ)をSQLで表現するには二重否定文に直すこと。具体的には「〜でない行が1つも存在しない」。そしてこれはNOT EXISTS、さらにその中で否定の条件を使うことで表現する。
  • 11章がなんだかんだ有用。著者は私の独創と呼べるような見解は一つもありません。なのであまり話すこともなし。さらっと目を通してくれればかまいません。って書いてるけど。
  • NOT EXISTS は HAVING で書き換えられるが、パフォーマンス的にはEXISTSを使ったほうがいい。インデックスも使えるし、条件を満たさない行が見つかれば探索を打ち切るから。HAVINGは集約されてしまうので情報が減ってしまうのも良くない。しかしNOT EXISTSは二重否定なので可読性は下がる。
    • Redash / Supersetみたいな色んな人が見そうなツールのSQLにはHAVINGのほうが良さそう。遅いって言われそうだけど。
  • 検索条件の左辺は裸。そうしないとインデックスが使用されない。
    • WHERE col_1 * 1.1 > 100; はNGで、 WHERE col1 > 100 / 1.1 ならOK。
  • IS NULL や IS NOT NULL を指定するとインデックスは使用されない

感想

ささっと読めるかと思ったけど演習問題をやりながらだと時間がかかった。
実行計画的な話とかもあるのかと思ったけどそれはなかった。このあたりをもうちょっと知りたい。
あとはもうちょっとたくさんSQL書く練習したいかな。 あと第2版は読んでみたい。