何で読んだの?
- 社内の勉強会で「達人に学ぶSQL徹底指南書 第2版」を読んだけど理解できない部分があったため「もしやそもそもの知識が足りないのでは~~?」と考えた
- 市の図書館に置いてあったから
あなたどんな人?
- 元診療放射線技師(医学物理士持ち)現在SIer2年目
- Web系開発やったり業務システム作ったりしている、最近は保守改修案件多め
- SQLはそれなりに書ける。RDBよく使う、パフォーマンスチューニングは理解できてない
学びになったこと
3章: エンジニアもコスト感覚を身に着けるべし
- 今まで考えたことなかった…!と思ったから
- 「なぜシステムにお金を払うのか?」→ 対価としてお客様が利益を受け取るため
という根本的な観点を見失っていた自分に気づいた。 - 会社(顧客)は「リリースしたら投資回収したい」のだ!
- じゃあコストってどう考えるの?
⇒ TCO(Total Cost of Ownership)で考えよう!- TCO: システム導入してから廃棄するまでにかかるすべての金額
- TCOは①イニシャルコストと②ランニングコストに分けられる
-
イニシャルコスト≒ライセンス料
- プロセッサライセンス: CPUの性能で料金が決まる。いい性能なら高い
- ユーザーライセンス: ユーザーの数で決まる。多いと高い
社内だけで使います、って感じならユーザーライセンスのほう
が安くできるかも?多いユーザーを想定するならプロセッサライセンスのほうがいいのかも?とか考えられる。
-
ランニングコスト≒サポート料
そもそもサポート無しは危険なのでやめよう
サポート料を拡張して考えたのがサブスク。結局使えば使うほどお金かかるのでTCOで考えよう。
-
4章: DBのアーキテクチャ
- ここもあまり勉強してこなかったので理解できてよかった
- ここでのアーキテクチャ: システムを作り上げるための物理レベルの組み合わせのこと
アーキテクチャは文脈でいろんな意味になるので要注意単語 - DB=DBサーバ+ストレージ
がセットになっているもの。これを「どのようなセットで持つことで”1個壊れても代わりがいるもの”」方式にもっていくかがポイント。 - 結局増やせば増やすほどコストは上がる。
- 歴史を追ってみると理解が深まる
- スタンドアロン(~1980年代)
- クラサバ(1990~2000)
- Web3層(2000~現在)
- スタンドアロン
- 問題点がいくつか
- 物理的に離れた場所からアクセスできない
マジで直接触って操作とかになる。無理。 - 複数ユーザーによる同時制御ができない
何人かが同時にアクセスしてデータをSELECTできるとかができない。 - 可用性が低い: 壊れたらサービスが停止する
- 拡張性が低い: 足りなくなっても性能を足すことができない
- 物理的に離れた場所からアクセスできない
- 問題点を解決したい…!!⇒ ネットワークにつなごう! ⇒ クラサバへ発展
- 問題点がいくつか
- クラサバ
- スタンドアロンをネットワークにつないでみたよ
再び問題点が生まれる…- セキュリティリスク ↑↑
- 管理コストが上がる
個々のPCにインストールして使うネイティブアプリがかつては主流だったが、時代を経ていろんな製品が出てきたことにより対応が難しくなってきた ⇒ DBとクライアント側もっと分けない? ⇒ Web3層へ発展 - 可用性・拡張性はWeb3層でメモ
- スタンドアロンをネットワークにつないでみたよ
- Web3層
- ネットワークにつないでデータをいい感じに冗長(コピーして保険として持てる)にできるようになってきた
- 数を増やして壊れても代わりがいる状態にしていく(人間に肺が二つある、みたいな感じ)。2パターンある
- クラスタリング: DBサーバーを複数台持つ
- レプリケーション: DBサーバーとストレージのセットを複数持つ
- まとめるとこんな感じ
5章: DBMSについて
- SIerしてるので普段めっちゃいろんなDBMS触る。あんまり意識できてなかったので勉強になった
- コネクション=電話かけるイメージ
- RDBには階層がある
- 基本4層。インスタンス(=タスクマネージャーから見えるプロセスの単位)>データベース>スキーマ>テーブル
- スキーマ: フォルダのイメージ
SQLServer、Db2、PostgreSQLが該当 - MySQLとOracleは特殊。変則3層
- MySQL: データベースとスキーマを同一視している
- Oracle: インスタンスの配下に一つしかデータベースを作れない(4層だけど実質3層)
7章: トランザクションについて
- トランザクション=複数のクエリを一貫性のある形でひとまとめにしたもの
- SELECT→UPDATE→SELECTのクエリをひとまとめにしたとすると、このひとまとめがトランザクション
- 4つの特性を持つよ
- 原子性: ひとまとまりのクエリが「全部成功するか」「全部失敗するか」を保証する仕組み
- 一貫性: データを変更してもルールを守る仕組み
例)UPDATEいくらかけてもUNIQUEなルールはずっと一貫している - 分離性: それぞれの処理が「矛盾なく」行えることを保証する仕組み
⇒これが同時実行制御の話につながるのでミソ - 持続性: 操作が永続的となり、結果が失われないこと
- このうち「分離性」が同時実行制御の時に効いてくる!
- 同時実行制御: 二人の人が同じテーブルを同時に操作した時の制御のこと
- これをいい感じに制御したい⇒トランザクション分離レベルを適切に設定しよう!となる
- 結論言っちゃうと実運用では「Read Committed」もしくは「Repeatable Read」を使おう
8章: テーブル設計の基礎
- 正規化(第1~第3正規形)をちゃんと理解した!
- そもそも何で正規化するの?⇒ 更新異常を減らしたい
更新異常: ミスって変なデータで更新しちゃった!ってのを減らしたい。 - ポイントは「テーブルは集合であり関数である」ということ
- よく参考書で出てくる「関数従属性」という言葉の意味をきちんと理解するとよくわかる
関数従属性: ある値が決まればそれに紐づく要素が一意に決定すること
y=axの関係。説明するとむずいな!
IDがわかればユーザーは一人に絞れる、ということ。 - 正規化はこのy=axの関係がいい感じになるようにルール化されている
- 第一正規化:一つのセルに複数のデータを入れないこと
⇒IDがわかってもユーザーを一意に絞り込めないよね。 - 第二正規化:複合主キーの時限定。複合主キーのいずれかのみが別の列に関数従属していたらテーブルを分けよう
- 第三正規化:主キー以外の項目に注目。その中で関数従属が発生していたらそのテーブルも分けよう
- 第一正規化:一つのセルに複数のデータを入れないこと
10章: パフォーマンスについて
- 勉強会でやったけどまじでわからんかった。改めて理解できてとても勉強になった
- パフォーマンスは2つの観点で理解するといい
- 処理時間+応答時間のこと。まとめると「レスポンスタイムがいかに短いか」ということ
- スループット: 単位時間当たりにたくさん処理できるか、ということ
- DBはどうしてもコストといい性能のバランスを取った製品を選択しないといけないため、効率を考えるとボトルネックになりがち。性能上げたければ金をよこしな!
⇒ お金は有限なのでチューニング(SQLの実行時間を短く)しようという考えが生まれる。 - とはいえSQLって関数型プログラミングと全然処理の流れが全然違う
- なんならユーザーにどんなロジックでデータを持ってくるか見せてくれない
- 実は内部的にロジックを勝手に考えてくれてデータを持ってきてくれているらしい
- チューニングするために人間様ができるのは「ロジックのえさになる情報を与えることだけ」
⇒適切にインデックスを貼ろう。適切なインデックス=ロジックのえさになる
インデックス: 列のデータに目次(索引)を付けること - どの列にインデックスつければいいの?
- テーブルサイズが大きく、列の中身がよりバラエティに富んだ列(カーディナリティが高い、という)に対してインデックスを付ける
- 主キー制約やUNIQUE制約のついている列に対してはインデックス不要。すでにインデックスがついているから
まとめ
- 基礎知識の基礎知識を身に着けるのにナイスレベルな書籍と感じた
- 次は「達人に学ぶSQL徹底指南書 第2版」にリベンジしたい