書籍概要

Software Design plus

SQLの苦手を克服する本 データの操作がイメージできれば誰でもできる

著者
発売日
更新日

概要

本書は,SQLの文法は学んだもののSQLに苦手意識を持っているITエンジニアのための書籍です。
複雑なSQLを読める/書けるようになるには,データベースの表をカタマリで操作する考え方(集合志向)を理解する必要があります。本書では,「データベースの表をカタマリで操作するイメージ」を持てるように,文法の解説はいったん脇に置き,どのようにイメージすれば良いか,ほかの手続き型言語とどう違うか,というポイントを豊富な図を使って入念に解説します。
また,SQLやデータベースで起こりがちな性能,メンテナンス性,開発効率などの問題を解決するには,データベースのしくみを理解し,アプリケーションとデータベースの役割を適切に分担する必要があります。こちらについても,さまざまな図と例を使って,問題が起きるメカニズムと解決のアイデアを紹介します。

こんな方におすすめ

  • SQLの文法を学んだばかりの人
  • SQLに苦手意識を持っている人
  • データベースのトラブルに苦労している人(性能,メンテナンス性,開発効率)

サンプル

目次

第1章 SQL再入門

  • エピソード1 SQLは集合指向の言語と心得よう
    • 1.1 本番システムの商品一覧画面が遅い!
    • 1.2 原因はアプリ側でデータ集計を行っていたこと
    • 1.3 なぜアプリ側でSQL発行ループを書こうとしてしまうのか?
    • 1.4 SQLは「集合指向」言語です
    • 1.5 役割分担が適切にできていない
  • エピソード2 SELECT文はカタマリを切り出す形でイメージしよう
    • 2.1 SQLで大事なのは「表形式のカタマリを操作する」イメージ
    • 2.2 表形式のデータ操作イメージを持つとは
    • 2.3 表形式のデータ操作イメージを描く方法
  • エピソード3 結合条件と抽出条件の違いとは
    • 3.1 ON句の本当の意味が知られていない?
    • 3.2 SELECT処理の流れをイメージしよう
    • 3.3 結合条件と抽出条件を区別する
    • 3.4 OUTER JOINのWHERE句で内部表側のカラムを使っていたら要注意
    • 3.5 再び,SQLはイメージで考えよう
  • エピソード4 複雑な場合分けロジックもCASE式で一発解決!
    • 4.1 月末の会員情報更新処理,どうしよう?
    • 4.2 テーブルを全件走査するUPDATEは減らしたい
    • 4.3 条件項目更新型UPDATEの分割実行に注意
    • 4.4 CASE式とパラメータテーブルを活用する
    • 4.5 会員ランク更新処理を実装しよう
    • 4.6 集計と更新の一発化はできない?
    • 4.7 CASE式はSQLに小回りの効く記述力を与えてくれる
  • エピソード5 ExcelでSQL操作のイメージをつかむ法
    • 5.1 正しい理解には現実世界のイメージを持つことが大事
    • 5.2 複雑な場合分けをパラメータで処理
    • 5.3 CASE式にパラメータテーブルを組み合わせる
    • 5.4 2万ステップのJavaがたった3つのSQLに?
    • 5.5 Excel計算式でSQL感覚をつかむ法
  • エピソード6 「INよりEXISTSが速い」神話の真実と相関サブクエリ
    • 6.1 INとEXISTSの違いを見極めるポイントとは
    • 6.2 選択性の高低を意識してINとEXISTSを使い分けよう
    • 6.3 INとEXISTSの処理の流れをつかもう
    • 6.4 しくみを理解して相関サブクエリも使いこなそう

第2章 SQLとデータベースのしくみ再入門

  • エピソード7 データベースがSQLを処理する流れを理解する
    • 7.1 「ループ」が引き起こす3つの問題
    • 7.2 DBとAPの役割分担を考えるための見取り図
  • エピソード8 実行計画で実際のアルゴリズムを把握しよう
    • 8.1 ぐるぐる系SQL,使っていませんか?
    • 8.2 しくみを理解せずに使えば一発系も遅くなる
    • 8.3 実行計画の確認はSQLチューニングの基本!
  • エピソード9 インデックスが効くときと効かないときの違いとは?
    • 9.1 自分が教える側になれば一番よく勉強できる
    • 9.2 インデックスがない検索はなぜ遅い?
    • 9.3 インデックスが効くと無駄なページを読まずに済む
    • 9.4 「しくみ」がわかっていないと真の応用は利かない
  • エピソード10 JOINのアルゴリズムを理解する
    • 10.1 SQLから「逃げる」ほど問題は悪化する
    • 10.2 3種類のJOINアルゴリズム
    • 10.3 SQLはしくみを理解して使うことが重要
    • 10.4 回避できるデメリットはデメリットではない
    • 10.5 JOINを使うと高コストになる?

第3章 アプリケーションとデータベースの役割分担

  • エピソード11 データベースで集計するほうが低負荷になる
    • 11.1 SQLで集計をすると処理を分散できない?
    • 11.2 DBで集計したほうが低負荷になる理由とは
    • 11.3 負荷はピークではなく面積で考える
    • 11.4 低い階層の動作イメージを持つことが重要
  • エピソード12 「スケールアウトしにくいからJOIN禁止」という間違った考え方
    • 12.1 開発元がギブアップしたシステムの改修依頼
    • 12.2 バッファプールが「ぐるぐる系」に影響しない理由とは?
    • 12.3 スケールアウトしにくいからJOINを禁止する?
    • 12.4 マスタ系データをコピーする方法
    • 12.5 JOIN禁止はかえって負荷を増やす
  • エピソード13 NoSQLはRDBのサブセット?
    • 13.1 大は小を兼ねる……わけではない
    • 13.2 RDBが登場した理由
    • 13.3 NoSQLが登場した理由
    • 13.4 RDBとNoSQLの使い分け

第4章 間違ったデータベース設計とそれを修正するアイデア

  • エピソード14 インジェクション対策のためにもSQL動的組み立ては避けよう
    • 14.1 任意条件の検索機能を作りたい
    • 14.2 SQLの動的組み立てはSQLインジェクションに弱い
    • 14.3 パラメータクエリでインジェクション回避
  • エピソード15 Entity-Attribute-Value手法はやめよう
    • 15.1 使い物になる技術知見の広め方
    • 15.2 根強く使われているEAVアンチパターン
    • 15.3 EAVを使いたくなる3パターン
    • 15.4 RDBの得意分野を正しく理解して使おう
  • エピソード16 EAVや非正規形のテーブル設計を少しずつ修正する方法
    • 16.1 EAVのコードはメンテナンスしづらい
    • 16.2 EAVの名称マスタを少しずつ移行する方法
    • 16.3 非正規形のテーブルを正規化したい

第5章 開発を効率よく進めるためのアイデア

  • エピソード17 SQLのための仕様書は書くだけムダ
    • 17.1 書類を増やしたからといって役に立つとは限らない
    • 17.2 SQLは人間が現実世界で使う言語に近い
    • 17.3 SQLは「要求」レベルを記述する言語
    • 17.4 SQL自体が仕様書のようなもの
  • エピソード18 O/Rマッパーを使うべきか・使わないべきか
    • 18.1 O/Rマッパーで起きがちなN+1問題とは
    • 18.2 O/Rマッパーを使っていいとき・悪いとき
    • 18.3 SQLは考え方さえわかれば簡単な言語
    • 18.4 インピーダンス・ミスマッチとは?
    • 18.5 SQLを理解してO/Rマッパーを使うなら問題はないが
  • エピソード19 テーブル設計の変更で大きな手戻りを発生させない方法
    • 19.1 新規開発やりますよ!
    • 19.2 「テーブル設計は後まわし」の真意とは?
    • 19.3 インターフェース仕様書を書いてスタブ自動生成
    • 19.4 DBアクセスをAPI化する「APIファースト開発」
  • エピソード20 データベース担当とアプリ担当は分けたほうが良い
    • 20.1 ベテランSEでも意外にRDBとSQLのことは理解できていない?
    • 20.2 プログラマは交換可能な部品扱いだった
    • 20.3 DB担当とAP担当は分けたほうがいい
    • 20.4 担当を分けてAPIファースト開発を!

サポート

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2022年11月8日最終更新)

P.30,図3-3

特待生フラグ=0の
特待生のデータしか
表示されなくなってしまった
削除フラグ=0の
特待生のデータしか
表示されなくなってしまった

(以下2022年2月1日更新)

P.38,4行目

見てのとおり結果(1)と結果(3)は同じです。1対1または1対多関係のテーブルをJOINする場合はINNERでもOUTERでも同じ結果が得られます。
見てのとおり結果(1)と結果(3)は4行目以外同じです。結果(3)に対して「WHERE 0 = B.DelFlag」で抽出すると結果(1)と同じ結果が得られます。

P.38,8行目

やはりご覧のとおり1対1(1対多)関係をJOINして得られる結果(5)と(7)は同じです。
この場合は1対1(1対多)関係をJOINして得られる結果(5)と(7)は同じです。

(以下2019年9月3日更新)

P.37,図3-6,結果(3)

誤

正

商品一覧