目次
第1章 SQLとリレーショナルモデル
1.1 そもそもSQLって?
- リレーショナルモデルを知らなくてもSQLは書ける?
 - RDBはリレーショナルモデルを正しく実践してこそ真価を発揮する!
 
1.2 リレーショナルモデル
- リレーションの定義
 - 集合とリレーショナルモデル
- 集合とは
 - リレーショナルモデルとNULL
 - 有限集合と無限集合
 
 - リレーションの演算
- 制限(Restrict)
 - 射影(Projection)
 - 拡張(Extend)
 - 属性名変更(Rename)
 - 和(Union)
 - 積/交わり(Intersect)
 - 差(Difference)
 - 直積(Product)
 - 結合(Join)
 
 - コラム 要素にNULLが含まれていると……
 - クロージャという性質
 - リレーショナルモデルにおけるデータ型
- データ型と変数
 - ドメインとは
 
 
1.3 SQLにおけるリレーション操作
- SELECTの基本形
 - コラム 拡張の評価順
 - INSERT(挿入)
 - コラム Relvar
 - DELETE(削除)
 - UPDATE(更新)
 
1.4 SQLにあってリレーショナルモデルにないもの
- 要素の重複
 - 要素間の順序
 - リレーションの更新
 - トランザクション
 - ストアドプロシージャ
 - NULL
 
1.5 まとめ
- コラム リレーショナルモデルは古典的か
 
第2章 述語論理とリレーショナルモデル
2.1 述語論理とリレーショナルモデル
- 命題
 - 命題論理
- 結合子
 - 真理関数の真理値
 
 - トートロジーと定理
- トートロジー
 - トートロジー=定理
 
 - 命題論理と公理系
- 公理
 - 公理系のサンプル
 - 背理法についての追記
 - 公理系を用いた証明のコツ
 - きわめて厄介なPrinciple of explosion
 
 - コラム プリミティブな演算子
 - 命題論理の限界と量化
- 命題論理の限界
 - 量化
 
 - 量化子と述語論理
- 述語論理
 - 量化子とともに用いる束縛変数
 - 量化子を伴わない自由変数
 
 - 述語論理と集合論
- 述語と集合は等価に置き換えが可能
 - 集合の包含関係
 - 集合と要素の包含関係の違い
 
 - 述語論理の公理系
- 述語論理の公理系の導出規則
 
 - ドメイン
 - 一階述語論理
 - 二階述語論理
 - リレーションの真の姿
- リレーションの演算は論理演算
 
 - 閉世界仮説
 - 矛盾したDBは役に立たない
 - コラム リレーショナルモデルの限界
 
2.2 リレーションの演算と述語論理
- 制限(Restrict)
 - 直積(Product)
 - 結合(Join)
 - 積(Intersect)
 - コラム 結合と制限
 - 和(Unoin)
 - 差(Difference)
 - 射影(Projection)
 - 属性名変更(Rename)
 - 拡張(Extend)
 - コラム 外部結合について
 
2.3 まとめ
第3章 正規化理論(その1)―― 関数従属性 ――
3.1 なぜDB設計は重要なのか
3.2 正規化
- リレーショナルモデルを補完する理論
 - 異常を防ぐことができる
- 異常が生じた例
 - リレーションの設計が常識的におかしい
 - なぜ異常が起きるのか
 - 異常を起こす原因は重複
 
 
3.3 正規形
- 正規形の種類
 - 第1正規形(1NF)
- カラムや行の順序
 - 重複する行をなくす
 - NULLが含まれてはいけない
 - 値のアトミック性
 
 - コラム 列の値はスカラであるべき?
- 繰り返しグループ
 
 - 候補キーとスーパーキー
 - 関数従属性(FD)
 - 第2正規形(2NF)
- 無損失分解
 
 - 第3正規形(3NF)
 - ボイスコッド正規形(BCNF)
 - コラム 候補キー内部に自明ではない関数従属性は存在しないのか
 
3.4 まとめ
第4章 正規化理論(その2)―― 結合従属性 ――
4.1 結合従属性(JD)
- 結合従属性は無損失分解が可能
 - 関数従属性は結合従属性の一種である
 - 暗黙的な結合従属性
 - 非キー属性と結合従属性
 - コラム なぜ非キー属性があると,候補キーを無損失分解可能な結合従属性が存在しないのか
 
4.2 結合従属性による正規化(4NF~6NF)
- 第4正規形(4NF)
 - 第5正規形(5NF)
- 接続の罠
 - 直積と結合従属性
 - 結合従属性を発見するのは難しい?
 
 - 第6正規形(6NF)
 
4.3 まとめ
第5章 リレーションの直交性
5.1 リレーションの直交性と重複
- レプリカ
 - 同じ型を含むリレーション
 - 見出しの一部だけが同じリレーション
 
5.2 リレーション直交化のための戦略
- 正規化
 - 属性(カラム)の名前を統一する
- 命名規則を統一する
 - 主語を含める
 
 - アプリケーションの整合性
 - すべてを直交化する必要はない
 
5.3 重複を解消することのメリット
- 異常を防げる
 - 必要なデータがどこにあるかが明確になる
 - クエリの記述が宣言的になる
 - 不要な無損失分解が必要ない
 - 複雑な制約が必要ない
 - アプリケーションのコードに無駄がなくなる
 - 性能が向上する
 
5.4 まとめ
第6章 ドメインの設計戦略
6.1 ドメイン
- ドメインとは
 - 集合の要素
 
6.2 ドメインの設計戦略の概要
- すべては恣意的な選択
 - アプリケーションの要求から生まれる
- 適切なDB設計に必要なこと
 - ドメイン駆動設計
 - DBのリファクタリング
 
 - データの本質を見極める
- 数値に文字列カラムを割り当てる例
 - DBは本質的なデータを扱うようにする
 
 - 属性(カラム)の名前
 
6.3 IDを設計するという考え方
- 現実世界の物体や概念を表す手段
- ナチュラルキーとサロゲートキー
 - どちらを使うべきか
 - ナチュラルキーの使いどころと問題点
 - サロゲートキーの使いどころと問題点
 
 - リレーショナルモデルにおけるキー
 - 意味を含んだID
 - コラム 紙の呪縛
 - IDの欠陥は波及する
 - 色,長さ,重さなどの性質を表す属性
 
6.4 SQLによるドメインの表現
- 適切なデータ型を選ぶ
 - 述語を制約で表現する
 - ドメインをテーブルとして表現する
 
6.5 まとめ
第7章 NULLとの戦い
7.1 NULL
- NULLとは
 - 3値論理(3VL)
- NULLは演算を台無しにする
 - 検索結果が意図しないものになる可能性
 - NULLによる第3の論理値
 - 想像以上に厄介な3VL
 
 - 3値論理の限界
- Unknownと曖昧さ
 
 - コラム 量子コンピュータとNULL
 - NULLは閉世界仮説に反する
 - オプティマイザへの弊害
 
7.2 NULL対策
- テーブルを正規化する
 - 誤ったNULL対策
 - COALESCE関数
 - 空文字列の扱い
 - NULLを使っても良いケース
 
7.3 まとめ
第8章 SELECTを攻略する
8.1 SELECTはSQLの心臓部
- SELECTの本質
- SELECTの強大さ
 - データを取得する唯一の手段
 
 - SELECTの基本構造
 
8.2 SELECT七変化
- 集約関数
- 関数の有無だけで意味が変わる
 - COUNTの特殊性
 - GROUP BYによる集約の書式
 
 - サブクエリ
- テーブルサブクエリ
 - スカラサブクエリ
 - 行サブクエリ
 
 - ビュー
 - UNION
 - 組み合わせは自由
 
8.3 リレーショナルではない操作
- リレーショナルな操作のおさらい
 - ソート
 - 明示的に定義されていないカラム
 - ストアドファンクション(ユーザ定義関数)
 - コラム 集約とGROUP BY
 - リレーショナルではない操作の扱い方
 
8.4 インデントでSELECT文を読みやすくする
- インデントのルール
 
8.5 まとめ
第9章 履歴データとうまく付き合う
9.1 履歴データの問題点
- 世界は履歴データで溢れている
 - 履歴とリレーショナルモデルの相性問題
 - 履歴データの具体例
 - 履歴データの何が問題になるのか
- リレーションと時間軸の直交性
 - NULLの可能性
 - 特定の行だけ意味が違う
 
 
9.2 履歴データに対する解決策
- リレーションを分割する
 - 最もシンプルな分割方法
- 外部キーが使用できない
 - 2つのテーブルの整合性
 
 - 重複した行を許容する
 - サロゲートキー
 - 未来の価格はどうすべきか
 
9.3 履歴データのアンチパターン
- フラグを立てる
 - コラム フラグのお化け
 - 手続き型として実装する
 - コラム テーブルを分けたときの物理的なメリット
 
9.4 まとめ
第10章 グラフに立ち向かう
10.1 グラフの構造
- ノード,エッジ
 - 隣接
 - 次数
 - 歩道,小道,道
 - 多重辺
 - ループ
 - 閉路
 - 連結
 - 部分グラフ
 - カットセット,ブリッジ
 - エッジの向きと重み
 - グラフの応用例
 
10.2 グラフの種類
- 一般グラフ
 - 単純グラフ
 - 連結グラフ/非連結グラフ
 - 完全グラフ
 - 正則グラフ
 - 平面グラフ
 - 有向グラフ/無向グラフ
 - 重み付きグラフ
 - ツリー(木)
 
10.3 SQLとグラフの相性問題
- グラフに対するクエリ
 - 無向グラフを表現できるか
 - 有向グラフを用いた表現
 - リレーショナルな視点でモデルを理解する
- 行列を用いた表現
 
 - グラフに対するクエリ
 - 手続き型による解法
 - グラフDB
 - コラム FlockDB
 - そのほかの問題
 
10.4 ツリー(木)
- ツリーはグラフの一種
 - コラム ディレクトリのハードリンクが作成できない理由
 - 隣接リストモデル
- NULLが許容される理由
 
 - 経路列挙モデル
 - 入れ子集合モデル
- 入れ子集合をテーブルで表現する
 - リレーショナルモデルと相性が悪い理由
 
 - クロージャテーブル
 - ツリーとSQLに関する考察
 
10.5 まとめ
第11章 インデックスの設計戦略
11.1 インデックスの働き
- RDBのインデックス
 - インデックスの左端と範囲検索
 - セカンダリインデックスの更新
 
11.2 インデックスの種類
- ハッシュインデックス
 - 全文検索インデックス
- 形態素解析
 - Nグラム
 
 - Rツリーインデックス
 - 関数インデックス
 - ビットマップインデックス
 - コラム クラスタインデックス
 
11.3 パーティショニング
- パーティショニングとは
 - パーティショニングが適しているケース
 - パーティショニングと一意性制約
 - パーティショニングについてよくある誤解
 
11.4 リレーショナルモデルとインデックス
- インデックスはリレーショナルモデルの一部ではない
 - 正規化とインデックス
- カラム数が絞られる
 - 問題児NULL
 
 
11.5 指令:最適なインデックスを探せ!
- 必要なインデックス
 - インデックスのアクセス特性
 - インデックスが使用される構文
- WHERE句
 - JOIN
 - 相関サブクエリ
 - ソート
 - カヴァリングインデックス
 - ORとインデックス
 
 - 最適なインデックスを探すための戦略
- インデックス ≠ 候補キー
 - カラムの並び順
 - カーディナリティ
 - 最適な組み合わせを探す
 - 難しい作業に立ち向かう
 - 真の最適解にこだわらない
 
 - コラム こんなインデックス設計はゴミ箱行きだ!
 
11.6 まとめ
第12章 Webアプリケーションのためのデータ構造
12.1 キャッシュという考え方
- メリット/デメリット
- メリット
 - デメリット
 
 - DBアプリケーションにおけるキャッシュ
 - キャッシュはあくまでもキャッシュ
 - キャッシュとして使うための要件
 - キャッシュすべきデータの種別
- キャッシュすべきではないデータ
 - キャッシュが可能なデータ
 
 
12.2 キャッシュの実装方法
- NoSQLをキャッシュとして使う
- 論理データはRDBで管理する
 - データ同期の際の注意点
 
 - コラム NoSQLでRDBは置き換えられるか?
 - テーブルをキャッシュとして使う
- 集計テーブル
 - 結合済みのデータ
 - ディスクI/Oを削減できる
 - ソートとの相性が良い
 - NewSQLとの相性が良い
 - タグ
 
 - コラム 転置インデックスを使用して検索を高速化する
 
12.3 スケールアウト
- レプリケーション
- レプリケーションのしくみ
 - スレーブへの問い合わせ方式
 - データの論理的整合性と非同期レプリケーション
 
 - シャーディング
- シャーディングのしくみ
 - シャーディングの最大の問題点
 - NoSQLのシャーディング
 
 
12.4 まとめ
第13章 リファクタリングの最適解
13.1 リファクタリング
- DBのリファクタリングは大変
 - マルチアプリケーションにおけるDB環境
 - なぜリファクタリングが必要なのか
 - リファクタリングの手順
 - スキーマの移行期間
 - 反復的なリファクタリング
- 回帰テスト
 - ベンチマークテスト
 - マイグレーション利用のススメ
 - トリガーを使って2つのテーブル間で同期を取る
 
 
13.2 リファクタリングの種類
- インデックスの追加・削除
 - カラム名の変更
 - NOT NULL制約の導入
 - 主キーの定義変更
 - 無損失分解
 - テーブルの垂直分割と統合
 - コラム 関連テーブルの実態
 
13.3 リファクタリングのためのベストプラクティス
- 正規化と直交性
 - カラムではなくテーブルを追加する
 - SELECT * を使わない
 - アプリケーションを疎結合に
 
13.4 まとめ
第14章 トランザクションの本質
14.1 トランザクション
- トランザクションの機能
- 同時実行制御
 - クラッシュリカバリ
 
 - トランザクションの鍵,スケジュール
- 処理の並列化は必要不可欠
 - 同時自動制御の鍵,スケジュール
 
 - 「データの正しさ」の定義
 - スケジューラの性能
 
14.2 トランザクションの特徴
- ACIDとは
- 原子性(Atomicity)
 - 一貫性(Consistensy)
 - 分離性(Isolation)
 - 永続性(Durability)
 
 - さまざまな異常
- ロストアップデート
 - インコンシステントリード
 - ダーティリード
 - ノンリピータブルリード
 - ファントムリード
 
 - スケジュールとロック
 - デッドロック
 - トランザクションの分離レベル
 - MVCC
 - クラッシュリカバリ
- DBサーバのコンポーネント
 
 
14.3 トランザクションとデータモデルの融合
- リレーショナルモデルとACIDの「C」
 - リレーショナルモデルと異常
 - 正規化と直交性
 - 制約
- データモデルだけでは不十分である理由
 - 制約を活用してデータを守る
 - NOT NULL
 - 一意制約
 - CREATE TYPE
 - CHECK制約
 - 外部キー制約
 - トリガー