「達人に学ぶDB設計徹底指南書」を読みました
勉強記録
今日は「達人に学ぶDB設計徹底指南書」を読みながら、DB設計について学びました。
以下、今日学んだことをまとめます。
データベースの代表的なモデル
データベースは、データを保持するフォーマットを基準にして分類される。
-リレーショナルデータベース
関係データベースとも呼ばれ、最も広く利用されている。
-オブジェクト指向データベース
オブジェクトをデータベースに保存するためにつくられたもの。
-XMLデータベース
XML(HTMLのようにタグでデータ管理を行う言語)形式のデータを扱うことができる。
-キー・バリュー型ストア
-階層型データベース
データを階層構造(木構造)で表現するデータベース
システム開発の設計工程
大きな分類としては
1.要件定義
2.設計
3.開発(実装)
4.テスト
システムの進め方(開発モデル)には大きく分けて2つの方法がある。
1.ウォーターフォールモデル
waterfall = 滝。滝の流れのように、要件定義→設計→開発→テストの順で、1つずつ工程を踏んで段階的にシステムを作っていくやり方。
滝は逆流しないように、ウォーターフォールモデルも基本的に工程を逆戻りすることはない。
右にいくほど(開発やテスト)スケジュールもタイトになり大変になりやすい
2.プロトタイピングモデル
prototype = 試作品。最初に小さな試作品を作って、顧客やユーザーからフィードバックをもらい、それを参考に改良版を作って・・・というようなサイクルを繰り返す循環的なやり方。
早い段階からシステムの具体的なイメージを共有できるので、意思疎通の齟齬が防げる。
一方で、変更を繰り返すうちに収集がつかなくなるというリスクもある。
プロトタイピングモデルを応用したのが「アジャイル」と呼ばれるモデル。
DOAとPOA
DOAはデータ中心アプローチという意味で、システムを作るときに、プログラムよりも前にデータ設計から始める方法。
現在ではDOAがほとんど。
DBから設計するべきだし、そもそもDBとして「独立」して設計するべき。
論理設計と物理設計
論理設計 テーブル設計 カラムはどうするのかなど・・・
物理設計 サーバーのディスクサイズやバージョンはどうするかなど
論理設計のステップ
まずは保存したいデータを列挙していく
↓
「正規化」 正規化とはデータをテーブルにする作業。正規化を踏まえて、見やすく、パフォーマンスにも強いテーブルを作成する。
↓
ER図の作成 ER図とはテーブルどうしの関係を表す図。
物理設計について
データベースの性能問題の8割はディスクI/Oによって起きる。
I/Oとはインプット/アウトプットのことで、読み書きのことを表している。
他に、リード/ライトとも呼んだりする。
ユーザーが少ないときは問題ないけど、ユーザーが増えるとデータ量も多くなり、障害の原因に
リードに関しては、インデックスを貼ることで問題を解消
ライトに関してはDBの分割(シャーディング)で問題を解消
パフォーマンスのサイジング
システム開発での性能要件の指標は「どれだけ多いか」「どれだけ速いか」の2つである。
-スループット 単位時間あたり何件処理をこなせるかを示す(どれだけ多いか)
<重要!>
QPS (クエリパーセカンド) 1秒あたりのクエリ数
IOPS(インプットアウトプットパーセカンド)1秒あたりのディスクが処理できるI/Oアクセス数
ex) 秒間1000のアクセスがあるので、100TPSさばけるサーバーが10台必要
もしサーバーが50TPSだったら、サーバーは20台必要
サーバーが1台あたり、どれくらいの処理をさばけるのか知っておく必要がある。
→パフォーマンステスト(負荷試験)を行う
-処理時間
特定の処理が何秒以内で終わるか(どれだけ速いか)
ストレージの冗長構成
障害対策
RAID(レイド)複数のハードディスクを組み合わせて、1台のハードディスクのようにして、性能をよくしたり一部が壊れてしまっても、大丈夫なようにしている技術のこと。
正規化について
正規化はデータをテーブルに落とし込むこと。
正規化にはレベルがあり、よく知られているものは第1〜5正規形があるが、普通は第3正規形まで理解してればOK。
※正規化については文章でまとめるのは難しいので、テーブルの例などを見ながら覚える!
正規化のポイント
1.正規化は更新時の不都合を防ぐもの
正規化することで更新やデータ登録時の不都合を防ぐ。また、データの重複部分などがないのでデータ管理がしやすい。
2.従属性を見抜くことが大事
正規化を行うには、テーブル内部を意味のあるもので分けたり、重複するものを分けたりと、従属性を見抜くことが大事。
3.正規形はいつでも非正規形に戻せる
正規化によってテーブルを分割しても、情報を完全に保存する「無損失分解」だから、元に戻すことができる。
ER図
テーブルが多いと見にくくなってしまう。
でも正規化は必要なので、テーブル間の関係性がわかるようにER図の作成する
テーブルのパターン
1対1
1対多
多対多
1対1は普通は一つのテーブルにまとめてしまっても問題ないから、正規化の過程で1対1のテーブルが作られることはない。
1対多というのは、例えば会社名と社員の関係など。会社名が1に対して、その会社に属する社員は多数となる。
多対多というのは、たとえば学生と講義の関係。学生も多数だし、講義も多数である。
これを管理するには、学生コードと講義コードを複合ユニークキーとした中間テーブルをつくる。
非正規化とパフォーマンス
正規化のしすぎ→SQLが遅くなる(たくさんJOINするから)
その場合、非正規化するか「検討」する必要がある。
正規化とパフォーマンスはトレードオフの関係
基本的に正規化→問題がでたら、非正規化するか検討したりNoSQLをつかうとか考える
統計情報
つまり、ユーザーからSQLを受け取って、どのような経路でデータを探しに行くのが効率的なのかを自分で判断している。
統計情報はデータへの最短距離を知るための地図である!
オプティマイザと実行計画
↓
↓
パーサのチェックが終わると「オプティマイザ」に渡される
パフォーマンスを牛耳っている
実行計画を決めるのがオプティマイザの役割
オプティマイザは「カタログマネージャ」に統計情報の照会をかける。
カタログマネージャは統計情報を管理するモジュール
↓
実行計画が決まると、それに従ってテーブルにアクセスする
SQLのパフォーマンスが劣化するときがある
→そんなときはオプティマイザに「どうやって実行しているのか」をきけるコマンドがある(EXPLAIN:エクスプレイン)
アンチパターン、バッドノウハウについて
設計の段階でクリティカル(危険)なミスを減らす
→後で取り返しのつかないことになる場合もある。なんとかなったとしても、莫大なコストや時間がかかってしまう。
真似してはいけない、やってはいけない設計パターンのことを
アンチパターンはたくさんあるので、業務を通して覚えていくべし
テーブルの分割
テーブルの分割のことをシャーディングという。
テーブルの分割には水平分割と垂直分割の2種類がある
なぜテーブルを分割するのか?
→I/Oコストの増大を解決するため、特にライトのパフォーマンス上の問題を解決するため
なぜテーブルの分割がバッドノウハウなの?
→テーブルを分割するということは、それだけDBのサーバーがわかれるからすごく大変