増永良文 リレーショナルデータベース入門[第3版]読書メモ
増永良文著 リレーショナルデータベース入門 [第3版]を読む
アカデミックな本らしい
第1章
- データ: 記号の集まり
- 意味: データに意味解釈を与えたもの
- 情報: 意味が受け手の持っている知識と比較して増える場合のもの
- 価値付き情報: 受け手の価値観に従って価値を有すると判断された情報
概念モデル
実世界が認識され記号化されたもの
ERモデルとか
論理モデル
概念モデルをDBMSで管理可能な形式に変換したもの
リレーショナルデータベーススキーマとか
概念スキーマと呼ばれるもの
ERモデルとリレーショナルデータモデルの違いを認識できてなかった。
ERモデル
実体を個々の実体として認識しようとするのではなくて,総体としてとらえようということである.たとえば,学生を認識するときに,学生のA君,Bさんという認識をするのではんくて,A君,Bさん等々をひっくるめて,抽象的「学生」というとらえ方をしよう,ということである
言われてみればそうだけどその認識はなかった
関連型
実体型との関連を表す関連型を導入
-
R(関連型)が多対多のとき、その主キーは和集合K⋃Hである -> ちょっとよくわからなかった 複合主キーは直積なのかと思ってたけど…
-
弱実体型: 実体型と組になることで一意に識別できる型
-
所有実体型: 弱実体型に一意識別能力を与える実体型
-
部分キー: 所有実体型の主キーと一緒にすると弱実体を識別できる属性
-
識別関連型(ID関連型): 所有実体型と弱実体型の関連
ERモデルは(中略)実世界の記述にユニーク性がない
- 学生と科目の関係を関連型としてとらえることもできるし、実体型としてとらえることもできる
第2章 リレーショナルデータモデル
~2.5
- ドメイン(定義域): 集合、有限集合でも無限でもいい
- タップル: ドメインの直積の元
- リレーション: 有限個ドメインの直積の任意の有限部分集合
- 濃度(cardinality): リレーションのタップルの総数
- ドメイン関数: 属性名からドメインへの写像
- リレーションスキーマ: 有限の属性名を集めたもの
- リレーションが時変なのに対して、リレーションスキーマは時不変である
- リレーションスキーマをドメイン関数で写像したものをリレーションスキーマのインスタンスという
リレーションスキーマRである性質Pが成り立つということは、RのすべてのインスタンスR'に対してその性質Pが成り立つときおよびそのときのみである
リレーションスキーマを定義していくことがデータベース設計者の仕事、インスタンスを作成していくことはデータ入力作業にあたる
~2.13
-
ドメインがシンプルである: ドメインの元が原始的(atomic)、すなわち分解不可能な値であること
- 他のドメインの直積は許されない
-
第一正規形: リレーションの各ドメインがシンプルであること
-
候補キー: リレーションのタップルを一意識別できる属性の集合で、極小のもの
- リレーションスキーマには候補キーは必ず存在する
-
空は値ではない
- 従って、空値(null value)という表現はおかしい
-
空の意味は14種類もあるらしい
- unk (unknown): 属性値は存在するが、未知である
- dne (does not exisit): 属性値は存在しない
- ni (no-information): 属性値が存在するのかしないのか、わからない
-
表明(assertion): リレーション定義とは別でデータベース全体でみたすべき制約
「上司よりも高給を取っている社員がいてはいけない」表明
CREATE ASSERTION 給与制約
CHECK (NOT EXISTS
(SELECT X.*
FROM 社員X, 社員Y, 部門Z
WHERE X.所属 = Z.部門番号
AND Z.部門長 = Y.社員番号
AND X.給与 > Y.給与))
第3章 データ操作言語
リレーショナル代数
リレーショナル代数: データ操作言語の1つ
8つの演算を持つ
- 4つの集合演算
- 和集合
- 差集合
- 共通集合
- 直積
- 4つのリレーショナル代数に特有の演算
- 射影
- 選択
- 結合
- 商
和両立(union compatible): 次元が同じ、ドメイン関数が同じ
- ドメインが同じであればいいので、属性名は異なっていても良い
集合演算
和集合演算: 和両立のリレーションR, Sに対して、
差集合演算: 和両立のリレーションR, Sに対して、
共通集合演算: 和両立のリレーションR, Sに対して、
直積演算(Cartesian product):
リレーショナル演算
射影: 列の取り出し
選択: 行の取り出し
-
θ比較可能: ドメイン関数が等しい、かつ任意のタプルtに対して、
の真偽が常に定まるt[A_i]\theta t[A_j] -
θ選択演算:
とA_i がθ比較可能な時、A_j R[A_i \theta A_j] = {t | t \in R \land t[A_i] \theta t[A_j} -
またはt[A_i] がnullを取る可能性がある時、3値論理に拡張する必要がある。t[A_j] - 商品[売価 >= 500] みたいな演算はリレーション代数に入っていない。定値リレーションを導入すると同様に定義できる
-
-
θ結合演算:
とA_i がθ比較可能な時、B_j R[A_i \theta B_j ]S = {(t, u) | t \in R \land u \in S \land t[A_i] \theta t[B_j]} - 直積と、θ選択演算で定義できる:
R[A_i \theta B_j ]S = (R\times S)[R.A_i \theta S.B_j]
- 直積と、θ選択演算で定義できる:
自然結合、外部結合をフォーマルに定義してる。数式長いので省略
商演算: divisor(割る方のリレーション) を全て含むタプルを抽出(割る方の列はなくなる)
-
なので(R \times S) \div S = R 記号が使われてる\div
リレーショナル代数表現
リレーショナル代数表現(relational algebra expression): 要するにクエリ
これを定義したいモチベがあまりわからなかった
3値論理
IS 演算子の真理値表
TRUE | FALSE | UNKNOWN | |
---|---|---|---|
TRUE | TRUE | FALSE | FALSE |
FALSE | FALSE | TRUE | FALSE |
UNKNOWN | FALSE | FALSE | TRUE |
マジでそのまま
推量θ選択演算
θ演算の結果が不定のタプルだけ出す、と読めるけどそれ定義して何が嬉しいのかよくわからず
リレーショナル論理
わかったような、わからんような
リレーション
DBにデータ操作言語
リレーショナル完備:Lがリレーショナル完備(relational complete)とは、
SQLはリレーショナル完備である
4章
-
リレーションがその分解成分の自然結合を取ると復元できるとき、その分解を情報無損失分解であるという
-
情報損失分解: リレーションを適当に分解すると、自然結合したときにもとのリレーションにはないタップルが出現する
- これを結合のわなという
- フォーマルには、
R \subseteq R_1 * R_2
情報無損失分解の一意性
このときRに多値従属性があるという
自明な多値従属性
を自明な多値従属性という
関数従属性
関数従属性は多値従属性の特殊な場合である
関数従属性
完全関数従属性
関数従属性
推移律
反射律
添加律
推移律、添加律、反射律を合わせてアームストロングの公理系という。
アームストロングは、以上3つを仮定すると関数従属性を全て証明できることを示した。
陽に宣言された、つまり所与の関数従属性の集合
閉包
Fから導出される関数従属性の全体(
リレーションスキーマRの属性集合Xについて、Fに関する閉包を求める問題を含意問題という
- アルゴリズムはp100
含意問題の応用として、リレーションスキーマRに関数従属性の集合Fが与えられた時に候補キーを求める問題がある。
候補キーは関数従属性を使って次のように定義できる
-
の閉包K K^+ = \Omega_R -
のどのような新部分集合に対して前項が成立しないK
求め方
-
の属性集合Xがスーパキーかどうかは、R を計算して、X^+ ならスーパキーX^+=\Omega_R -
の各要素Aに対してX を作り、その閉包を求める。そのうちどれかが\{X-A\} になれば、スーパキーではあるが候補キーでない。\Omega_R -
とR が与えられた時に、F は少なくともスーパキーである。これに対して再帰的に前2つの操作を適用すれば候補キーがもとまる\Omega_R
F の閉包
-
の閉包を求めるのには一般に指数オーダーの時間がかかるF
等価性
関数従属性の集合
-
にF が存在すれば、X\rightarrow Y のX に対する閉包G を求め、それにX^+ が含まれているかを調べれば良いY
極小被覆
- (a)
とG は等価F - (b)
の全ての関数従属性は、単一の属性G を使って、A の形X\rightarrow A - (c)
に関数従属性G とX\rightarrow A の真部分集合X が存在して、Z がG-\{X\rightarrow A\} \cup \{Z \rightarrow A\} と等価でないG - (d)
の関数従属性G が存在して、g がG-\{g\} と等価でないG
アルゴリズムはp105へ
- 多項式オーダー、
O(|\Omega_R|^2 \times |F|^3) - 極小被覆は唯一に定まらない(このため最小被覆とは言わない)
第2正規系 (2nd normal form; 2NF)
-
は第一正規系である。R -
の全ての非キー属性はR の各候補キーに完全関数従属している。R
非キー属性: いかなる候補キーにも属していない属性
完全関数従属: 関数従属であり、あらゆる真部分集合に対して関数従属でない
第3正規系 (3rd normal form; 3NF)
推移的関数従属性
X \rightarrow Y -
でないY \rightarrow X Y \rightarrow Z
とする。ただし、
このとき、
X\rightarrow Z -
でないZ \rightarrow X
が成立する。このとき、 を推移的関数従属性と呼び、X \rightarrow Z はZ に推移的に関数従属するとよぶX
第3正規系の定義
- (1)
は第2正規系であるR - (2)
の全ての非キー属性はR のいかなる候補キーにも推移的に関数従属していないR
ボイスコッド正規系 (BCNF)
要は候補キーから候補キーへの推移的関数従属性を禁止する正規系っぽい
-
は自明な関数従属性である。X \rightarrow Y -
はX のスーパキーであるR
第3正規系であることは含まれている?
- BCNF 分解は関数従属性を保存しない
第4正規系 (4NF)
次のいずれかが成立することをいう
-
は自明な多値従属性であるX \rightarrow\rightarrow Y -
はX のスーパキーであるR
結合従属性
このとき、リレーション
第5正規系 (5NF)
-
は自明な結合従属性である*(X_1, X_2, \dots X_n) - 各
はX_i のスーパキーであるR
ここでが自明であるとは、
第5正規系への分解は、第4正規系が関数従属性を保存しなかったように、結合従属性を保存しない。
さっぱりわからん
合成的手法によるデータベース設計
リレーションを徒に高次に正規化するのではなく、第3正規系止まりとするのが良いのではないかと言う共通認識ができている。バーンシュタインが示した合成的手法(sythesis approach)により、関数従属性保存、第3正規系、情報無損失分解が揃ったデータベース設計が行える。
-
の極小被覆F を一つ見つけるG -
を決定子に持つX の全ての関数従属性G に対してX\rightarrow B_1 \dots X\rightarrow B_k とし、リレーションスキーマY=\{B_1 \dots B_k\} を作る。この操作をR(X,Y) の全ての関数従属性に対して行う。その結果、G を得る\{R_1(X_1, Y_1) \dots R_m(X_m, Y_m)\} -
の中に\{R_1 \dots R_m\} の候補キーを含むリレーションスキーマが存在すれば、これが所望の分解である。もしそうでなければ、R の候補キーの一つをR としてK を作ると、R'(K) が所望の分解である\{R'(K), R_1, \dots R_m\}
5章 SQL
知っていることは飛ばす
- リレーションは集合であり、同じタップルが表れることはなかったのに対し、SQLの表はmultisetである
- SELECT句は射影演算、FROM句は直積演算、WHERE句は選択演算
- したがって処理は、FROM -> WHERE -> GROUP BY -> HAVING -> SELECT の順
SQLのリレーショナル完備性
リレーショナル代数の5つの独立な演算、和、差、直積、射影、選択が存在することを示す
- 和: UNION
- 差: EXCEPT
- 直積: 結合
SELECT R.*, S.*
FROM R, S
- 射影: SELECT
- 選択: WHERE
PL/I
まあいいか
動的SQL
こんなんあるんだ。
今ならクエリビルダがやっちゃいそう。
まだ使われてるのかな。
オブジェクト指向拡張
- ROW型
CREATE TABLE 学校(
学校名 NCHAR VARYING(20),
所在地 ROW(町 NCHAR VARYING(10), 区 NCHAR VARYING(10), 郵便番号 CHAR(8))
)
INSERT INTO 学校
VALUES (N'お茶の水小学校', ROW(N'大塚', N'文京', '123-4567'))
- ユーザ定義型
CREATE TYPE 学校型 AS(
学校名 NCHAR VARYING(20),
所在地 ROW(町 NCHAR VARYING(10), 区 NCHAR VARYING(10), 郵便番号 CHAR(8))
)
- メソッドを定義できる
- サブタイプ(継承)が定義できる
CREATE TYPE 大学型 UNDER 学校型 AS (学部名 NCHAR VARYING(10))
6章 DBMS標準アーキテクチャ
ANSI/X3/SPARC がDBMSの3層アーキテクチャを定義している
ロール
- 組織体管理者
- データベース管理者
- アプリケーションシステム管理者
機能
- 概念スキーマプロセッサ
- 外部/概念データベース変換
データ辞書
メタデータのデータベース
3層スキーマ
概念スキーマ
リレーショナルモデルとかネットワークモデルとかハイアラキカルデータモデルとかオブジェクト指向データモデルとか
内部スキーマ
ISAMファイルやB+ treeとか
概念スキーマをストレージ/コンピュータシステムを実装するための構文的・意味的構造
データベース管理者が内部スキーマを定義する
- マジで?日常用語のDBAと割と意味が違う気もする(言語やアルゴリズムを実装することはないと思う)けど、ここにインデックス貼るといいとかそういう話をしている?
- 構文的・意味的構造って何〜
外部スキーマ
ビューのこと
あるいはUIとか(アプリケーションを含んでいるのか不明)
データ独立性
物理的データ独立性
1つのリレーションは1つのファイルで実装される。
- リレーション <-> ファイル
- タップル <-> レコード
- 属性 <-> フィールド
ファイル中のレコードの位置決めをする方法をアクセス法(access method)という
要はファイルシステムやアクセス法をDBユーザに影響を与えずにできること = 物理的データ独立 ということらしい
論理的データ独立性
アプリケーションプログラムを実世界の変化による概念スキーマの変化から不変に保つこと
- そんなことできんの?
アプリケーションはビューだけに依存しろと言っているように聞こえるが実際どれぐらい守られているのか不明
- ビューを使っても更新時に異状が発生する場合がある。詳しくは次章
DBMSの3大機能
- メタデータ管理
- 質問処理
- トランザクション管理
メタデータ管理
- 概念スキーマ、外部スキーマ、内部スキーマを格納する
- システムカタログ: どのようなリレーションにどのような情報が入っているかの情報
- カタログリレーションとして実装
実体は DEFINITION_SCHEMA
と呼ばれるスキーマに格納される。これはプログラマが直接いじれないようになっている。
代わりに INFORMATION_SCHEMA
というビューの集まりを参照できる。
質問処理
内部スキーマレベルのアクセスコードを生成する処理
RDBMSの場合、質問は非手続き的なため、DBMSが処理コストが最小のアクセスコードを生成する必要がある(詳しくは9章)
トランザクション管理
障害時回復(recovery)と同時実行制御(concurrency control) 12章で
7章 ビュー
ビュー更新問題
結合ビューへの更新は意味的曖昧性を持っており必ずしも現実世界を反映しない。
ただし選択ビューは更新可能である
ビューの更新可能性
なんか色々あるが便利な結論が出ていないのを理解した
体現ビュー
OLAPやDWHで積極的に使われる
8章 ファイル編成とアクセス法
-
ファイル編成: ファイルを編成するレコード群の間にどのような関係性があるかの設定
-
アクセス法: ファイルから所望のレコードをどのように見つけ出すか
ファイル編成
- ヒープ編成: レコードが二次記憶に書き込まれた時刻順にレコードに順番を付ける直列編成ともいう
- アクセス方は基本的に線形探索
- 順次編成: ファイルを構成するレコードのあるフィールド(キー)の昇順または降順でソートして順番づけする
- 高速アクセス
- 削除、書き換え、挿入にともないソートし直さないといけないのが非効率的
- 直接編成: ハッシュ編成あるいはランダム編成ともいう。ハッシュ関数で二次記憶上の位置を求める
- 範囲問い合わせが非効率的
- ハッシュ関数に偏りがあると更新が非効率的
アクセス法
- 順次アクセス法: 先頭レコードから順に行き着く方法
- インデックス法: キーとレコードの格納番地の対応表(インデックス)を作成する
ヒープ編成ファイルにインデックスを貼ってもいいし、順次編成ファイルにインデックスを貼らずに順次アクセスしてもよい
ファイルスキャン
線形探索: O(n)
二分探索: O(logn)
ブロック探索:
以上総称してファイルスキャンという
インデックス法
インデックスは2項ファイルであって、第1フィールドはフィールドの値、第2フィールドはレコードの格納番地のポインタ
インデックスレコードのスキャンアクセスが可能
インデックスを用いてファイルのレコードの位置決めをする方法をインデックススキャンという
インデックスを張ったフィールドについてその順番でディスクに格納されているとき、FはAに関して順次という。このとき、Aを順序フィールドという
AがFの(候補)キーであるとき、Aを順序キーという。
順序キーに定義されたインデックスを1次インデックスという。
それ以外のインデックスを2次インデックスという。
2次インデックスの対象フィールドが候補キーでない場合、間接ブロックで二重参照してレコード特定する。
- DBMS上で候補キーかどうかって(自明な場合を除いて)わからないのでは?自明な場合で十分ということなのかな
Dense index: 順序インデックスで、全部の値をインデックスに格納
Sparse index: 順序インデックスで、一部だけ格納(ソートされているので、ないやつは間を走査すれば見つかる)
多段インデックス: 木でインデックスを表現(sparse indexの拡張)
順序キー上に多段インデックスを張ってアクセスする方法をインデックス付き順次アクセス法(Indexed Sequential Access Method: ISAM)という。
ISAMでアクセスするファイルをISAMファイルという
インデックスの1ノードに入る順序キー値とポインタのタプルの最大数をオーダーという
ナイーブな木でインデックスを構成すると、挿入時に非平衡木になってしまい、レコードによってアクセス回数のばらつきが出てしまう。
B+ tree
よくわからんけど葉ノードにデータポインタの個数の制約と、中間ノードにデータポインタが入らないようにする制約があるのがキモっぽい?
これによって平衡木が保たれる
キーの物理的な(ディスク上の)順序性は要求していない
レコード挿入
葉ノードに空きがあれば入れる。なければ、ノード分割する。
- ノード分割回数の最悪値オーダーがわからん。
レコード削除
ポインタが空にしたときに、データポインタ個数の制約に抵触する場合、きょうだいノードを見つけてデータポインタを再分配する。あるいは、自分とどちらかのきょうだいノードを合体する。
ハッシュ法
ハッシュ関数について書いてある
動的ハッシュ法について書いてある
9章 RDBMS の質問処理とその最適化
構文解析、最適化、コード生成、実行の4ステップで実行される
コスト式
単純質問処理
SELECT * FROM R WHERE A = 'a'
- ファイルスキャン
- セグメントスキャン
- 表スキャン(違いがわからん)
- インデックススキャン
結合質問処理
SELECT A, R.B, C
FROM R, S
WHERE R.B= S.B
brute force
- 表RとSの直積をとる
- R.BとS.B上の符号選択をとる
- R.A, R.B, S.C 上で射影する
直積を取るのがO(M*N)でとても効率が悪い(M, N はRとSの行数)
改善は以下
- 入れ子ループ結合法
- ソートマージ結合法
- ハッシュ結合法(等結合のみ)
入れ子ループ法
for each t in R
for each t' in S such that t[B] = t'[B]
compute t * t'
end
O(M*N)っぽく見えるが、SにBについてのインデックスが張られていることを前提とする。
DBMSは、片方のみにインデックスが貼られていたらそちらをインナー表にする。両方張られていたらコストを計算して低い方にする。(RとSの濃度の小さい方をアウター表にする、その差がなければインデックス表の大きさを比較して小さい方をインナー表にする)
ソートマージ結合法
結合列で共にソートされていることが前提
ややこしいので詳細は省略、ソートされているので最小限のスキャンで済んでいることがキモっぽい
スキャン数でいえば入れ子ループと変わらないがシーケンシャルリードになる(インデックス読むより速い)ので入れ子ループよりも速い
結合属性上にインデックスが張られている場合は、ソート順でアクセスできるので、事前にソートしなくて良い。
ハッシュ結合法
結合列のハッシュを計算してS(小さい方の表)との直積Hを計算する。
Hが主記憶に格納可能なら、h(b)からSのレコードを探索する(ハッシュが衝突する可能性があるため、これは一般に複数ある)
入れ子ループ結合法でいうインナー表を二次記憶にアクセスせず主記憶だけでアクセスできるのではやい
入れ子型質問処理のコスト
相関がない場合、足し算
相関がある場合、
Nは表の濃度
クラスタードインデックス
クラスタードインデックス: インデックスがフィールドの値の大きさ順で物理的に連続してブロックに格納されているとき。
そうでないとき、非クラスタードインデックスという。
一般に、XAがクラスタードインデックスならXBは非クラスタードインデックスである。
クラスタードな場合、RのデータフェッチコストはRの総レコード数の代わりに濃度で代用できる(おそらく、データページが連続なのでという理由)
10章 トランザクションと障害時回復
主記憶のデータが2次記憶に書き出されるタイミングはOS任せ、ページ置換アルゴリズムによる。
主記憶に書いてプログラム上トランザクションが終了したが、書いたデータが2次記憶に書き出される前に障害になった場合どうするか?
2次記憶に書かれたかどうかの状態遷移を管理して解決する。
プログラムが実行終了したらコミット待ち状態に遷移し、失敗したら失敗状態に遷移する。それぞれコミットが行われたらコミット状態、ロールバックが行われたらロールバック状態に移行する。
ACID特性
原子性(atomicity)
すべて処理が行われるか、全く行われないかの二者択一であるという性質
一貫性(consistency)
読んでもよくわからなかった。
よく考えるとフォーマルに定義しようとするとふんわりしてしまう気がする。
現実世界と照らし合わせて、変な状態にならないこと、というふんわりとした定義な気がする。(本文にもちゃんと書いてない気がする、データベースの状態だけ見て判断できるものではないとは書いてある。)
atomicityはconsistencyの必要条件だが、十分条件ではない気がする(知らんけど)
隔離性(isolation)
トランザクション同士が互いに影響を与えないこと。
耐久性(durability)
コミットしたトランザクションはその後障害が起きても失われることはない。
障害分類
- トランザクション障害
- システム障害
- メディア障害
REDOとUNDO
- トランザクションUNDO: トランザクション障害が発生した場合、異常終了したトランザクションをUNDOする
- 全局的UNDO: システム障害発生時点で、コミットもアボートもしてない全てのトランザクションを再スタート時にUNDOする。
- 局所的REDO: コミットしていたが、一部か全体がデータベースに反映されていない場合(バッファに書かれたが2次記憶にflushされていない場合)、再スタート時にREDOする。
- 全局的REDO: メディア障害時に、データベースの保管用ダンプ(archives dump)をもとに障害発生に至る間にコミットした全てのトランザクションをREDOする。
- メディア障害復旧後に、という意味だと思う。
障害回復作業時にも障害が発生する可能性があるので、UNDOとREDOは冪等でなければならない。
以上を実現する2つの方法
- ログ法
- シャドウページ法
ログ
ログは書き込みがあると直ちに安定記憶に強制書き込みされる。
(データページはOSのページ置換アルゴリズムに任せている)
波及ロールバック
ログにはトランザクションのreadも書いてある。
T1がアボートされたら、T1が書いたデータを読んでいたT2もアボートしないといけない(以下波及的にアボートの必要あり)から。
ただしこれはとても大変なので、T1が書いたデータをコミットするまでは他のトランザクションが読めないようにすることもある(2 phase lock)。この場合ログにREADは書かなくていい。
WAL (Write Ahead Log ログ先行書き込み)
リレーション更新がログ書き込みより先になると、リレーション書いてまだログを書いてない時に障害発生すると復旧不可能なので、ログを先に書く。
これをWALプロトコルと呼ぶ
コミット時点
トランザクションはいつ終了したと言えるか?
答えはログにcommitが書かれた時点(これをコミット時点という)である。
(アプリケーションのcommit文終了時でも、2次記憶に書いた時でもない。)
なぜなら、コミット時点以降はログをもとに必ず復元できるから。
即時更新、遅延更新
ログを書いたあと、リレーションをいつ2次記憶に書くかに2つバリエーションがある。
- 即時更新: コミット時点を待たずに2次記憶への書き込みを許す
- 回復は、REDOとUNDOを両方使う。
- 正常時の性能はこちらの方が良い
- 遅延更新: コミット時点以降に全て書く
- 回復は、UNDOを使わない。
チェックポイント法
- 実行中トランザクションを全て一時停止する
- データベースバッファを強制書き出しする
- チェックポイントレコードをログに書き出す
- 中断していたトランザクションを再開する
障害回復時にはチェックポイントまで遡れば良い
(ログには全て書いてある前提なのでチェックポイント作成中に障害が起きても何の問題もない)
シャドウページ法
ログを使わない障害回復方法。
実際のディスクブロックへのポインタを2つ(カレントページテーブルと、シャドウページテーブル)持っておいて、先にカレントページテーブルを更新して、トランザクションが正常に終わったらシャドウページを捨ててカレントページをシャドウページとして安定記憶にかく。
異常終了したら、カレントページを捨てる。
- ディスク上のページが転々とするのて、局在性を活かせない。
- 参照されなくなった古いページをガーベッジコレクションする必要がある。
- トランザクションのコミットのたびにカレントページテーブルを安定記憶にかくオーバーヘッドがある
- 同時実行が難しい
11章一旦飛ばす
12章 分散DBMS
透明性
DBユーザからの要求
- 位置に対する透明性
- 物理的にどのサイトにデータが格納されているかを意識する必要がないこと
- 分割に対する透明性
- 複数のサイトに分割してデータを保存したり移動したりしてもそれを意識する必要がないこと
- 複製に対する透明性
- 複数のサイトにデータを複製して保存していても、それを意識する必要がないこと
分散型メタデータ管理
- 集中方式
- グローバルデータ辞書を1つのサイトだけが有する方式
- 不整合が起きない
- SPOFになる
- 複製分散方式
- SPOF回避できる
- 複製伝播の問題がある
- サイトの自治権尊重方式
- 自分が持っていないメタデータを他のサイト聞いてキャッシュする
- ARPみたいなノリ…?
- System R* はこれ
なんか、raftやquorumに慣れ親しんだ身からするとある表はあるサイトにしかないというのが信じられない。
分散型入れ子ループ結合法: インデックスが張られている方がインナーリレーションである。インデックスは転送されないので、アウターリレーションは別サイトから転送して結合する(!?)
- 大変だなあ
分散型ソートマージ結合法: 転送コストが小さい方の表を転送して結合する
準結合演算
AとBを結合属性としたリレーションRとSの準結合
S[B]と結合しても結果は変わらないことに注意。これを使うと、Sの代わりにS[B]だけ転送して
分散型トランザクション管理
分散型トランザクションは、その実行のために各サイトでサブトランザクションを発行する。これは再帰的になり得るので、全体は木になる(トランザクション木と呼ぶ)
2 phase commit
- 第一相 投票相
- マスターサイトMはコミット準備を自分のログに書く
- 全ての従サイトにコミット準備をブロードキャストする
- 従サイトSiは次のいずれかを行う
- TiのログとTiのコミット準備完了レコードをログに書く。MにTiのコミット準備完了メッセージを投票する。
- 自分のログにTiのアボートレコードを書く。MにTiのアボートメッセージを投票する。
- 第二相 決定相
- 全てのサイトが投票を済ませたかタイムアウトしたらMはいずれかを行う
- 全ての従サイトからコミット準備完了を受け取った場合、Tのコミットレコードを自分のログに書く。コミットメッセージを従サイトに送る。各従サイトはコミットレコードをログに書く
- 全ての従サイトからコミット準備完了メッセージを受け取れなかった場合、TのアボートレコードをMのログにかく。全ての従サイトにアボートメッセージをブロードキャストする。各サイトは、Tiのアボートレコードをログに書く。
- 全てのサイトが投票を済ませたかタイムアウトしたらMはいずれかを行う
2PCでも万能ではない。
- Mが一相終了後にクラッシュした場合、従サイトは再起動を待たなければならない。従サイトは不定状態となる。
- Mが2相のアクションをとった(とりはじめた?)直後に従サイトがクラッシュすると、そのサイトは再起動後に不定状態となる。
- ackを受け取ってないから、ということだと思う
3 phase commit
ackを返すので不定状態にならないと書いてある
- あんまりわかってない
- Mが2相や3相でクラッシュした場合どうリカバリされるのか分かってない
13章 クライアントサーバーコンピューティングとデータベース
相互接続性と共通インターフェースの話が書いてある
OLTP (online transaction processing)
刻々と変化する実世界に対応して瞬時に多様なトランザクションを処理する。
さまざまなクライアントがネットワークを介してDBにアクセスするような、ふつーのDBを使うアプリケーションのことを言っている
OLAP (online analytical processing)
様々なデータを集計して1つの知識の塊にして意思決定を支援するシステム
スライシング: 多次元データベースから2次元の表を切り出す
ダイシング: 特定の値について多次元データベースをそのまま出す(次元は落ちない?)
SQL/PSMについて書いてある
11章 トランザクションの同時実行制御
同時実行制御しないときに起こる異状
- 遺失更新(lost update)
- あるトランザクションによる更新が別のトランザクションにより失われて不整合になること
- 汚読(dirty read)
- あるトランザクションが更新途中の値を別のトランザクションが読むこと
- dirty readした値を元にcommitしてしまうと、それより前には戻せないので回復不可能スケジュール(non-recoverable schedule)となる
- non-repeatable read
- トランザクション中に他のトランザクションがcommitした値を読むこと(dirty readはコミット前)
- とくに同じ結果を期待するread処理の結果がタイミングによって異なること
スケジュール
トランザクション集合をどのように同時実行していくかを表したトランザクションステップの系列
- 各トランザクションについて、すべてのステップが順番を保っている必要がある
- 同時(concurrent)は並列(parallel)ではない。ある一時点では実行されるステップは1つだけ
直列スケジュール
トランザクション集合を1つずつ実行した場合は必ず一貫性のある状態になる。
- 各トランザクションの実行順は問わない。
- トランザクションがn個あれば、
個の直列スケジュールがあるn!
- トランザクションがn個あれば、
- 実行順が異なる場合、最終的なデータベースの状態は異なるが、いずれも「正しい」
直列化可能スケジュール
同時実行スケジュールのうち一貫性を損なうことが決してないもの=直列スケジュール(のうちのいずれか )と等価であるもの
スケジュールの等価性
あるスケジュール
スケジュールの正当性と直列化可能性の定義が書いてあるが全く同じ定義に見える(なんで2つ用語定義した?)
トランザクション集合に対して直列化可能スケジュールが存在するかを判定する決定問題は、ナイーブに解くと階乗オーダーとなる。
制約を強くすると多項式時間で解けるようになる(相反直列可能性は多項式時間)
次の順で制約が強くなる
- 最終状態直列化可能性
- ビュー直列化可能性
- 相反直列化可能性
最終状態直列化可能性
各トランザクションでの最終書き込みの集合が同じである時、最終状態等価という
- write(x)の等価性の定義が書いてなくてよくわからん!
- なんで集合なのかわからん、元はいつもひとつだけでは?
ある直列スケジュールが存在して、最終状態等価のとき、最終状態直列化可能という。
最終状態直列化可能なとき、一般には直列化可能ではない
- なんでそんな名前つけたんだ…?
- ほぼ自明では?
ビュー直列化可能性
スケジュールSとS'がビュー等価であるとは、
- SとS'は最終状態等価
- 任意のSのステップsについて、sが初期読み込みなら、S'でもsは初期読み込みである
- 任意のSのステップsについて、sがそれに先行するステップs'の書き込み結果を読んでいるとき、S'のsでもそうなっている
ことをいう。
ビュー等価ならば、実行終了後のデータベースの状態は同じになる。
ある直列スケジュールが存在して、ビュー等価なとき、ビュー直列化可能という。
相反グラフ(conflict graph)
スケジュールSの相反グラフを次のように定義
- ノードをトランザクションとする
- ノード
からT_i に対して次のいずれかの場合に有向辺を張るT_j -
のreadがT_i のwriteに先行するT_j -
のwriteがT_i のwriteに先行するT_j -
のwriteがT_i のreadに先行するT_j
-
Sの相反グラフが非巡回なら、Sはビュー直列化可能である。ビュー等価な直列スケジュールは相反グラフをトポロジカルソートすることで得られる。
- Sがまずあって直列スケジュールを求められるって言ってる。Tの集合があってSを求められるとは言ってないのを理解するのにちょっとハマった
相反等価
SとS'ですべての相反しているステップの組の順番が同一であること
相反直列化可能
ある直列スケジュールS''が存在して、SとS''が相反等価であること。
Sが相反直列化可能であるための必要かつ十分な条件は、Sの相反グラフが非巡回であること。
トランザクションの集合から直列化可能なスケジュールを得る方法
- 2相ロッキングプロトコル
- 時刻印順序プロトコル
- 楽観的制御法
- 多版同時実行制御法(MVCC)
2相ロッキングプロトコル
read及びwriteする前にアンロックされることがないロッキングプロトコル
必要なロックを得る層(第一相、成長相)とロック解除する相(第2相、縮退相)があるので2相ロッキングと呼ばれる
あるトランザクションがロックしているデータを他のトランザクションがロックすることがないとい、順法(legal)なスケジュールという
デッドロック
ロック解除待ちがループしてトランザクションを進められなくなること
待ちグラフを書いてループしているかどうかを調べてデッドロック検出できる
DBMSはデッドロックを検出したらいずれかのトランザクションをアボートさせる。
デッドロック防止法
検出するのでなく、防止する方法もある
- wait-die scheme
- Tiがロックしようとしたデータを他のトランザクションTjがロックしている場合、Tjが年下なら待つ。年上ならTiをアボートする。
- wound-wait scheme
- Tiがロックしようとしたデータを他のトランザクションTjがロックしている場合、Tjが年下なら、Tjをアボートさせる。年上なら待つ。
MVCC
実行終了を待つのではなく、データの異なる版を用意することによってconcurrencyを高めるアプローチ。
MVCCアルゴリズム
- read(x)を
に変換する。r_i[x_k] はx_k 開始以下で最大のタイムスタンプをもつxの版T_i - write(x)を
- もし、
なるi j kでTS(T_k)< TS(T_i)<TS(T_j) が行われていたら、write(x)は棄却される(って何?)r_j[x_k] - そうでなければ、
に変換するw_i[x_i]
- もし、
MVCCアルゴリズムは「正しい」=直列化可能性が保証される
SQLの隔離性
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
ファントムリード、よくわからない
- 読み書きするデータにロックをかけたとしても検索条件にひっかかるものは他のトランザクションで一般に変わるって言ってる気がする
2PLで実現できるのはREPEATABLE READである
- データ項目でなく、表をロックしないとSERIALIZABLEにならない
MVCCを使ったとき、スナップショット隔離性という別のレベルになる。
14章 ビッグデータとNoSQL
CAP定理
共有データシステムにおいては、整合性、可用性、分断耐性の3つの性質のうち、高々2つしか両立させることができない。
分断耐性を放棄したのが従来のRDBMSであり、可用性を放棄したのがBigtableであり、整合性を放棄したのがDynamoである。
BASE
- Basically Available
- CAP定理の意味で可用(って何?)
- Soft-state
- 入力がなくてもシステムの状態が変化しうる
- Eventual Consistent
- 新たな更新がなく、障害がなければ、すべてのデータの複製はいつかは整合状態となる
結果整合性
- 強い整合性
- データの更新が完了した時点でどの複製にアクセスしても更新された結果(新しいデータ)を返すこと
- 弱い整合性
- 結果整合性
マスターは
クライアントからデータ検索要求が来たら、
このとき、次の関係がある
-
の場合、強い整合性で対処するW+R > N -
の場合、結果整合性で対処するW+R \le N
本文誤植あり
N=3, W=1, R=1 とするシステムが多い
完全に良書でした