DBの基本的な考え方

達人に学ぶDB徹底指南書を読んだ。
今まで自分でサービスを作る際にはプログラミングが大事だからプログラミングを勉強しよう!Railsを勉強しよう!Reactでスマホのネイティブアプリもjavascriptで作れるの?やってみたいな!みたいなことを思っていたが、実際のサービスというか今あるサービスのほぼほぼ全てにデータベースが利用されているので、データベースを知らないのは地図を持たずに森の中に入る感じだなと感じた。現に、素人はプロセスからサービスを作るが本当はデータベースからサービスを構築する方がいいらしいし。
 
以下の内容は読んだアウトプットです。
 
 
第1章
現在主流のデータベースはリレーショナルデータベース。これらを管理するシステムをDBMS。システムにおけるデータベースの役割は大きなもので長期的な運用を考えるとPOAではなく、DOAでデータを設計する。(素人はPOAで作る)このデータベース設計はシステム開発の要件定義、設計、開発、テストの設計の部分に当たる。データベース設計でユーザーから見た外部スキーマ、開発者から見た概念スキーマ(論理設計)、DBMSから見た内部スキーマ(物理設計)の三つの世界。
 
第2章
論理設計→物理設計の順で設計する。データベースで取り扱う実体(エンティティ)を決め、どのような属性(列)かを定義。データの整合性を高めるために正規化する。それに伴ってテーブルが増えてくるのでER図を作成し、分かりやすくする(机上で可能な作業)という論理設計の流れ。
データを入れるテーブルを定義し、データを検索しやすいようにインデックスする。データが増えてきたときに対処するために、データのサイジング(スケーラビリティの高さを向上)。障害発生時に対応するためのストレージ冗長構成で使う技術がRAIDであり、最もポピュラーなものがRAID5。どのファイルをどのディスクに置くかの物理配置はDBMSが自動的に配置してくれる。バックアップはフルバックアップ+差分バックアップorフルバックアップ+増分バックアップがポピュラー。
 
第3章
テーブルには重複行は使えない。外部キーを使った際には、子データから順に削除する。無駄なデータ領域と面倒な更新処理を防ぐのが正規形の役割。逆は結合。
第1正規形…一つのセルに一つの値を含む。
第2正規形...部分関数従属をしない。
第3正規形...推移的関数従属
正規化で更新時のデータ入力ミスを防止、正規化は従属性の理解でマスター。テーブルの増加に伴いパフォーマンスの低下。
 
第4章
ER図で複雑なテーブルも理解。相手のエンティティと対応するレコード数をカーディナリティ。
多対多の関係を防ぐために関連実態を用いる。
 
第5章
正規化をするとパフォーマンスが低下するので結合を行うことで対処するが、結合は最終手段。サマリデータや選択条件を冗長すると検索を高速化できる。
非正規化は更新時の不整合リスク、データのリアルタイム性の低下、改修コストを高めるというリスクを含む。
 
第6章
データベースのパフォーマンスを高めるにはインデックスと統計情報。
インデックスは本にページ番号をつけるようにアプリやデータの中身に対して影響を与えないが、無駄なインデックスは他の処理同様パフォーマンスに影響を与える。インデックスの中ではB-treeインデックスが汎用性が高く重宝できる。B-treeインデックスは大規模なテーブル、カーディナリティの高い列(列の要素の種類の多さ)
統計情報をエンジニアが直接的に実行計画には関与しない。ユーザーからSQL文が発行されたとき、文として正しいかDBMSでパーサ(文が正しいかチェック)し、実行するか決めるオプティマイザに文が渡される。オプティマイザがカタログマネージャーから統計情報を受け取り、それを元にテーブルへアクセスするという流れをDBMS内で行なっている。
 
第7章
非スカラ値...第1正規形を守る
ダブルミーニング…列は一度決めたら同じ要素を入れる
単一参照テーブル…同じ列に他の要素は含まない
テーブル分割(水平分割/垂直分割/集約)…拡張性、データ更新時の問題があり、他の代替え手段を用いるべき
不適切なキー...固定長文字列を用いる
ダブルマスタ...システム統廃合時に起こりやすい
 
第8章
グレーノウハウ
代理キー...主キーが決められない、主キーとして不十分なケースに用いるが推奨されることはない。代理キーの代わりに自然キーを使う方法としてタイムスタンプとインターバルの2種類がある。代理キーを使う際にはオートナンバリングを使う。
列持ちテーブル…シンプルで入出力のフォーマットに合わせやすいが、列の増減が難しかったり、NULLを使う必要があるので可能な限り行持ちテーブルにする。
場当たり的な集計キー…キーを別テーブルに分離したり、新たなビューを作成、GROUP BYでその場限りのキーを作成することで解決。
多段ビュー...基底テーブルを意識しないと、テーブルとビューの依存関係を分かりにくくする。
データクレンジング...一意キーを特定し、名寄せによって一元化する。
 
第9章
今まで木構造は隣接リストモデルを用いられていたが、入れ子集合モデルで木構造を表現する。更新時のパフォーマンスが弱いという点から入れ子区間モデルが拡張版としてあるが、理論上の話になる。他にも経路列挙モデルがあり、検索パフォーマンスが強い(ルートから各ノードまでの経路を保持する)。