絵で見てわかるOracleの仕組み (DB Magazine SELECTION)
- 作者: 小田圭二
- 出版社/メーカー: 翔泳社
- 発売日: 2006/06/21
- メディア: 単行本
- 購入: 27人 クリック: 385回
- この商品を含むブログ (48件) を見る
絵で見てわかるOracleの仕組み 小田圭二:著
単なる読書メモデース。久しぶりに専門書に近いもの読んだ気がする。
本書の内容
Oracleデータベースに関する運用/管理の実力は、コマンドや機能名を暗記するだけでは身につきません。そこで本書では、Oracleの基本操作を一般的なコンピュータ用語を用いて解説し、ハードウェアやOSの動作と合わせてOracleの仕組みを徹底的に“図解”します。図中ではOracleの仕組みを倉庫会社の仕組みに見立て、一見複雑に思える内部動作もイメージしやすくしています。日常の運用/管理業務に役立つだけでなく、応用力のあるエンジニアになるための知識が身につく1冊です。
本書は月間DB Magazineの人気連載「絵で見てわかるOracle入門」を、加筆/再構成し、書籍としてまとめたものです。
はじめに
はじめまして。日本オラクルでコンサルタントをしている小田と言います。筆者は、約8年前に日本オラクルの社内教育部門に入り、その後4年間以上、OracleやUNIX、ネットワークといった技術を日本オラクル社内で教えていました。その後、データベースのコンサルタントになり、ミッションクリティカルシステムばかり担当して5年ほど経ちます。OS,ストレージ、ネットワークといったOracle以外の技術にも強いことが筆者の売りの1つでしょうか。
筆者は社内教育部門に在籍していた当時、何百人ものエンジニアを教育しました。また、教えたエンジニアがどのように成長したのかも見てきました。DBコンサルタントになってからは数多くのお客様やSIerを見てきました。その経験上、典型的な「伸びないエンジニア」は丸暗記しているエンジニアと言えます。
アーキテクチャや動きを理解せず、「コマンドをこう打てばいい」とか、「よく分からないけど、こういうものなんだ」と暗記しているエンジニアは、そのときは良くても将来的には伸びません。
逆に、一般的なITの観点からOracleを理解しているエンジニア、Oracleのアーキテクチャを理解しているエンジニアは、応用も自由にでき、艦橋の変化や新技術の対応にもすばやいという傾向があります。Oracleといえど、その実体はディスクやネットワークを使うOS上のアプリケーションにすぎないためです。
ありがたいお言葉です。
本書の対象読者は次のとおりです。
知識の前提は、「基本的なSQL文(SELECT/INSERT/UPDATE/DELETE/COMMIT/ROLLBACK)」を知っていることです。
ゴメンなさい。基本的なSQL文知りません・・・・。
目次 第1章 I/Oとディスクの関係 Oracleを理解するための必須キーワード Oracleとディスク(ハードディスク) ディスクの動作 データを保証するためのディスク 第1章のまとめ 第2章 Oracleのさまざまなプロセス 本書におけるOracleのイメージ データベースのデータはみんなのもの Oracleが複数のプロセスで成り立つ理由 サーバープロセスとバックグラウンドプロセスの役割 各プロセスが行う処理 第2章のまとめ 第3章 キャッシュと共有メモリ なぜ、キャッシュが必要なのか そもそもキャッシュって何? データはブロック単位で管理する キャッシュの利用でインデックス検索が効率的に プロセスはキャッシュを共有する 共有メモリに必要な設定 共有メモリはどんな風に見える? バッファキャッシュを掃除するLRUアルゴリズム OracleだけでなくOSやストレージについても考えよう 第3章のまとめ 第4章 SQL文解析と共有プール なぜ、SQL文の解析と共有プールを学ぶのか SQL文と一般的なプログラミング言語の違い サーバープロセスと解析 最適な実行計画を判断するには 共有プールの動作と仕組み 数値で見る解析と共有プールの情報 第4章のまとめ 第5章 Oracleの起動と停止 なぜ、起動と停止を学ぶのか Oracleの起動/停止の概要 業務の開始に相当するOracleの起動 インスタンスとデータベースと主要ファイルの構成 起動処理の流れと内部動作 業務の終了に相当するOracleの停止 手作業でのデータベース作成 第5章のまとめ 第6章 接続とサーバプロセスの生成 なぜ、アプリケーションからの接続を学ぶのか Oracleの接続動作 接続動作の確認 停止やリスナーの状態確認 性能を改善するには 第6章のまとめ 第7章 Oracleのデータ構造 なぜ、Oracleのデータ構造を学ぶのか 可変長のデータを管理するためのプログラムを作るには Oracleのデータ構造 各データ構造はどのようなものなのか 実際の流れに沿って各動作を確認しよう プロセスから見たデータ構造 第7章のまとめ 第8章 Oracleの待機とロック なぜ、待機やOracleのロックを学ぶのか データベースにロックが必要な理由 待機とロック待ち ラッチの仕組み 第8章のまとめ 第9章 REDOとUNDOの動作 なぜ、REDOとUNDOを学ぶのか 持続性を実現するには REDOとUNDOの概念 REDOのアーキテクチャ UNDOのアーキテクチャ さまざまな状況におけるREDOとUNDOの動作 第9章のまとめ 第10章 バックアップ/リカバリのアーキテクチャと動作 なぜ、バックアップ/リカバリを学ぶのか バックアップ/リカバリに必要な知識のおさらい バックアップの種類と特徴 データベース破壊の例 基本的なリカバリの種類と動作 基本的なリカバリの流れ(データベース全体のリカバリ) その他のリカバリ 第10章のまとめ 第11章 バックグラウンドプロセスの動作と役割 なぜ、バックグラウンドプロセスを学ぶのか バックグラウンドプロセスとサーバープロセスの関係 DBWR(DBW)の動作と役割 LGWRの動作と役割 PMON(ピーモン)の動作と役割 SMON(エスモン)の動作と役割 アーカイバ(ARCH)の動作と役割 そのほかのバックグラウンドプロセス 第11章のまとめ 第12章 Oracleのアーキテクチャや動作に関するQ&A 前章までのおさらい Oracleの動作に関する質問 監視/運用に関する質問 解答と解説:Oracleの動作に関する質問 解答と解説:監視/運用に関する質問 まとめ 索引
目次書くだけでもうくたくた。自分なにやってんだろ、と時々思う。ただ、字幕読むと読書してたころの感覚がよみがえることがあるんで、重要なんスよ。
Oracleを理解するための必須キーワード
- 並列処理を可能にし、高スループットも実現
- レスポンスを重視
- COMMITされたデータは守る
・インデックスの使用例
例えば、ラリーさんのことを本で調べたい場合には、インデックスで240ページに書かれていることを調べてから該当ページを開き、ラリーさんの情報を得ます。SQL文も同じで、WHERE句に“ラリー”さんのことを知りたい旨の記述をし、SELECTの後に知りたい項目(次の例では“所属会社”)を書きます。SELECT "所属会社" FROM "個人データ" WHERE "個人名" = "ラリー";
なるほど、これがSQL文か・・。
第1章のまとめ
- ディスクが回転しているイメージ
- ヘッドが動き、さらに回転待ちをするため、I/Oに時間がかかるイメージ
- インデックスにより、該当データにすぐアクセスできる(先頭から読まなくて済む)イメージ
こういう、ハードウェアよりのお話って、好き。面白い。
「プロセス」と「スレッド」って何?
プロセスとは、実行状態であるプログラムのことです。実行状態であるため、メモリなどのリソースも持っています。言い換えると実体化しているわけです。
プロセスのイメージを説明すると、プログラムどおりに動く小人さんです。UNIX上で同じプログラムが複数実行されていても、それらは別々の小人さん(プロセス)となるため、CPUが複数あれば同時に処理されます。
それに対してスレッドとは、プロセス内に存在する実行単位です。1つのプロセス内で処理を並行して動作させたい場合に使用します。
どちらも並行して動くための仕組みですが、最大の違いはオーバーヘッドが大きいかどうかと、メモリを共有するかどうかです。スレッドの場合にはオーバーヘッドが少ないものの、メモリをスレッド同士で共有するため扱いに注意が必要です。
わかったような、わからないような・・。
Windowsの場合は、複数プロセスではなく、マルチスレッドで並列に処理します。以後、Windowsにおいては「プロセス」は「スレッド」に置き換えて読み進めてください。
はいさっ。
重要っす。この二つが強力してるから、いいレスポンスが出せるってことみたいです。
第2章のまとめ
データはブロック単位で管理する
# データが入っていないときのブロック
−−− ブロックヘッダ −−− 空き領域 −−−
↓
データが1行入ったときのブロック
−−− ブロックヘッダ −−− 空き領域 *** ←一行分のデータ。 −−− 行データはブロックの 後ろから順に入れていく
↓
#何行かデータをINSERTした後、何行かDELETEしたときのブロック。
これがデータを核のしている通常のブロックの状態と言える
−−− ブロックヘッダ −−− 空き領域 *** ←DELETEにより ***** 空いた空き領域。 *** ←詰め直すことはしない。 −−−
図のように、1つのブロックには複数の行が格納されているので、1行だけディスクから読み込むためだとしても、ほしい行を含むブロックごとキャッシュに置かれます。なお、ブロックサイズは2KB,4KB,8KB,16KB,32KBといったサイズから選べます。データの大容量化やキャッシュの大容量化により、最近のシステムでは8KBを採用することが多くなっています。ただし、大きな表をシーケンシャルアクセスで読み込まなければならないようなデータウェアハウスなどでは、16KBや32KBといったサイズが選ばれることもあります。
ファイルシステムのアロケーションユニットサイズみたいなもんですかね。
キャッシュに載っていない場合はI/Oだけで40msecになります。
それに対してこのような軽いSQLの処理に必要なCPU時間は、1−2msec程度です。トータルでは、キャッシュがない場合にかかる処理時間が41-42msecで、キャッシュにデータがある場合にかかる処理時間は1-2msecです。いかにキャッシュの効果が高いかということ、また、キャッシュに気をつけなければいけないことがご理解いただけると思います。
メモリ積みまくったら速くなるってことですね。
OSに対して行う共有メモリの設定例(Solarisの場合)
set shmsys:shminfo_shmmax=4294967295
set shmsys:shminfo_shmmin=1
set shmsys:shminfo_shmmni=100
set shmsys:shminfo_shmseg=10
「shm」から始まる設定が共有メモリの設定
Column 最近のバッファキャッシュサイズの考え方
かつて、バッファキャッシュのデフォルト値がたったの50ブロックだった時代があり、デフォルト値で運用しているお客様がこのパラメータを大きくしてみたところ、劇的に速くなるという時代がありました。また、そのころの設定ファイルには、設定値の例が示されていて、LARGE(大きな値の例)として3200ブロックという記述もありました。
昔はメモリが高価だったためですが、現在はずいぶんメモリの値段が下がり、考え方も変わってきました。最近では製品やOSの制限がなければ、数GBのバッファキャッシュにすることも珍しくありません。100GBという、一昔前では考えられないような設定もあるほどです。
Column 「セマフォ」って何?
共有メモリの設定と同様、呪文のように見えるのが、セマフォの設定です(LIST3)。セマフォとはOSが提供するリソース管理の仕組みの一種で、リソースの数に対して使いたいプロセスの数が多い場合には、先着順にリソースを使用させるというったプロセスの制御うが行えます。複数のプロセスが動作するOracleでも、プロセスの制御にセマフォが使われています。
set semsys:seminfo_semmni=100 set semsys:seminfo_semmsl=256 set semsys:seminfo_semmns=1024 set semsys:seminfo_semopm=100 set semsys:seminfo_semvmx=32767 これ(「sem」から始まる設定が セマフォの設定LIST3 OSに対して行うセマフォの設定例(Solarisの場合)
セマフォも基本的にはマニュアルどおりに設定すれば問題ありませんが、Oracle以外のアプリケーションでも使用されることがあるため、Oracle起動時にセマフォが不足している旨のメッセージが出た場合は増やすことも検討しましょう。また、誰も使用していないセマフォがOS上に残ってしまうこともあるため、掃除しなければならない場合もあります。その際には、ipcsコマンドやipcrmコマンドを使ってDBAが掃除することになります。
ふーむ。なんか難しい話だね。
バッファキャッシュのサイズは無限ではありませんから、誰かが何らかの方法で管理解除をしなければなりません。キャッシュに用いられるアルゴリズムとして一般に知られえいるのが、「LRU(Least Recently Used)アルゴリズム」です。簡単に言うと、最近使われていないデータからキャッシュアウト(捨てていく)するアルゴリズムです。OracleもバッファキャッシュにLRUアルゴリズムを用いています。OracleはLRUに基づくブロックのリストを持っていて、どのブロックが最近使われていないのかを把握しています。
最近はメモリが安価になってきたため、物理メモリを購入して、物理メモリ上のみで動くように各々のパラメータを設定するのがおすすめです。つまり、仮想メモリのためのディスクはあくまでも保険として用意しておく程度に留め、実際には使わない方針をおすすめします。
結論ってことで、いいんですね?
ハードパースは今まで説明してきた解析のことです。共有プールに実行計画がないので、事項計画も作成するケースです。ソフトパースはハッシュ値を求めた結果、共有プールにキャッシュされている実行計画が見つかったため再利用するケースを指しますつまり、今まで解析しないと説明していたほうです。鋭い方はお気づきかもしれませんが、実はSQL文の実行にあたってソフトパースすらおこなわないことがあります。とはいえ、ソフトパースすら行わないケースはそれほど多くありませんし、一般にソフトパースで十分効果が得られるため、ここでは割愛します。
第4章のまとめ
Oracleでは管理の単位として「インスタンス」という用語を使います。インスタンスとは、「バックグラウンドプロセス群+共有メモリ」のことです。
├─環境変数ORACLE_HOMEで指定されているディレクトリ | ├─binディレクトリ(Oracleのプログラム。 | | Oracleという名前のファイル、 | | SQL*Plusもkのディレクトリに、 | | 入っている | └─dbsディレクトリ(初期化パラメータのファイル。 | インスタンスのパラメータや制御 | ファイルの位置が置かれている。 ├─制御ファイル:データファイルやREDOログファイルの位置などが | 置かれている ├─データファイル:実際のデータが入っている ├─REDOログファイル:データ変更ログが入っている └─その他のファイル:アーカイブログや各種エラーログのファイルなど 初期化パラメータで場所が指定していされている ことが多い
LIST6 初期化パラメータファイルが正しい場所にない場合は?
SQL> startup ORA-01078: failure in processing system parameters LRM-00109: could not open parameter file '/home1/10g/app/oracle/product/10.1.0/db_1/dbs/inittest.ora'エラーが出て起動できない。「ORACLE instance started.」が表示されていないこと、すなわちNOMOUNTになっていないことに注目
◆起動処理のポイント
Oracleの起動に関する要点をまとめると、次のようになります。
- まず初期化パラメータファイルを読んで、バックグラウンドプロセスの生成と共有メモリ(バッファキャッシュや共有プール)の確保をする。これをNOMOUNTと呼ぶ
- 初期化パラメータファイルの記述にある制御ファイルの位置を確認し、制御ファイルを開いてデータベースを構成する各種ファイルの位置を知る。これをMOUNTと呼ぶ。なお、場所を知るだけなので、ファイルがなくてもこの時点ではエラーにならない
- データファイルやREDOログファイルに問題がなければ(Oracleが内部的に使用するデータきつじつまが合わないなどがなければ)、データファイルの読み書きが可能な状態にする。つまり,SQLを実行できる状態にする。これをOPENと呼ぶ。
shutdownのオプションとその動作
オプション 接続の終了を待つか 変更済みデータをデータファイルに書き込むか なし(デフォルト)※ 接続の終了を待つ YES transactional(トランザクショナルと読みます) トランザクションが終わるまで待つ。トランザクションが終わったら接続を切ってしまう。 YES immediate(イミディエートと読みます) NO。コミットされていないデータは失われてしまう。 YES abort(アボートと読みます) NO。コミットされていないデータは失われてしまう。 NO ※最近はコネクション(接続)プールの使用が増えてきました。一般に、コネクションプールはアプリケーションが終了するまで、接続を終了させません。そのため、コネクションプールではオプションの指定が必須の場合があります。
Column 制御ファイルの重要性
この章の説明で、制御ファイルの重要性を理解していただけたかと思います。データファイルという実際にデータが入っているファイルが壊れなくても、制御ファイルが壊れただけでデータベースは使えなくなってしまうのです。この制御ファイルには、データファイルなどの構成情報が入っています。そのため、データファイルの追加/削除、REDOログファイルに関する変更を行った場合には、制御ファイルのバックアップをとっておくようにしましょう。もちろん、普段のバックアップの際にも忘れずに制御ファイルのバックアップを取得しておきましょう。
Oracleでは、受信待ちしているプロセスを「リスナー」と言います(サーバープロセスではありません)。
1回のサーバープロセスの生成は、軽いSQL文の数倍から数十倍以上ものCPU時間を使用してしまうのです。しかし、最近になっても、サーバープロセスの生成が必要な物理接続と切断を繰り返すよう手アプリケーションを作成しているプロジェクトを見かけることがあります。みなさんはこのようなことをしないように注意してください。
本書でもサンプルユーザーとして、scott/tigerが出てくるように、scott/tigerは世の中に広く知られています。これにはどんな由来があるのでしょうか。実はscottは、初期の頃にOracleを作っていた開発者の名前(Bruce Scott)です。そして、tigerは彼の飼い猫の名前なのだそうです。たまに、本番環境のユーザーとパスワードにscott/tigerを使用しているDBAさんを見ることがありますが、みなさんは類推しやすいこのようてパスワードはやめましょう。
なお、Bruce ScottはOracleを辞めましたが、今でもたまに日本に来てセミナーなどを開いているので、そういう機会に運良くあうことができるかもしれませんね。
第6章のまとめ
この章では次の内容を説明しました。
- 接続のためにはデータベースサーバーのアドレス、リスナーのポート番号が必要
- tnsnames.oraというファイルに接続のための情報を書いておく(JDBC Thinドライバを除く)
- リスナーというプロセスが接続要求を受け付ける。サーバープロセスの生成も行う
- listener.oraというファイルにリスナーの設定(ポート番号など)を書いておく
- サーバープロセスの生成は非常に重いので、できる限り減らすべき
- 管理およびI/Oの効率を考えて、ある程度のサイズ以上にまとめて領域の割り当てをする
- データ変更用の空き領域を確保しておく
- 空き領域を管理しておく
(図解だったので、それっぽくテキストにしておく・・)
<論理構造(Oracle内部の構造)>
表領域:表領域とは、表やインデックスなどを入れるための領域(入れ物)
- 表領域(論理構造)は、1つ以上のデータファイル(物理構造)から構成されている
- 表領域(論理構造)は、1つ以上のセグメント(表など)
を格納できる
↓
セグメント:セグメントとは,表やインデックスなどの「データを格納するもの」のこと
- セグメント(論理構造)は、1つ以上のエクステント(ブロックのかたまり)から構成されている
↓
エクステント:主に管理をしやすくするためのデータの固まり↓
Oracleブロック:主に管理をしやすくするためのデータの固まり<物理構造(OSから見た構造)
データファイル
↓データファイルは複数のブロックから構成される
ブロック
表領域の集合(物理的にはデータファイルの集合)とREDOログファイル、制御ファイルが集まると1つのデータベースになります。
SQL> SELECT TABLESPACE_NAME FROM DBA_TABLESPACES; TABLESPACE_NAMESYSTEM ←データべースを管理するセグメントのための表領域 SYSAUX ←データベースを管理するセグメントのための表領域 UNDOTBS1 ←UNDOセグメントのための表領域 TEMP ←ソーとセグメントのための表領域 USERS ←ユーザー用の表領域 5 rows selected.
- -
第7章のまとめ
- 表領域はセグメントを入れるための入れ物で、1つ以上のデータファイルから構成されている
- 通常の表やインデックスはセグメントである
- セグメントはエクステントから構成され、エクステントは連続したブロックから構成される
- セグメントは表領域をまたげない(セグメントは表領域に所属するから)
- エクステントはデータファイルをまたげない(エクステントは連続したブロックだから)
- 通常、表やインデックスは、表領域の持つ空き領域から新たにエクステントを割り当ててもらうことにより、サイズが大きくなっていく
- ブロック内のデータ更新用の空き領域は、PCTFREEというパラメータで制御される
- 行はブロックに格納されている
管理用の表領域(SYSTEM表領域)には、ユーザー用のセグメントを作成してはいけません。間違ってSYSTEM表領域をパンクさせてしまうと大変だからです。
第8章のまとめ
- 待機とは待っているという状態をあらわしているにすぎない
- アイドル待機イベントとアイドルではない待機イベントがある
- ロックは処理を保護するためにある
- デッドロックはお互いが所有するロックを要求して処理が進まない状況である
- ロック競合を解消するためには、アプリケーション側で対処しなければならないことが多い
- ラッチはOracle内部の大事なもの(主にメモリ)を保護するためにある
- 大規模ではないシステムにおいてラッチ競合が激しいようごあれば、CPUリソース不足か、ページングなとの望ましくない状態になっていないかどうかも確認する
- Oracleを健全に動かすためには、土台となるOSも健全な状態でなければならない
ディスクI/Oの時間のほとんどは、いわゆる「頭出し」の時間で占められているのでした。この方法では大量のデータを変更した場合、COMMITに非常に時間がかかってしまいます。
そこで商用RDBMSの多くは、ログ(更新ログ)
を採用することによって、性能と持続性の両立を実現しています。Oracleも同様で、REDOログによって性能と持続性を確保しています。なぜREDOログによって性能が確保されるのかというと、REDOログにデータをまとめて書き込むことでI/O回数が減るためと、シーケンシャルアクセスになるためです。I/Oサイズが大きくなっても頭出しの回数は変わらないので、それほどI/O時間は延びません。
◆REDOのまとめ
-並列処理を可能にし、こうスループットも実現
--基本的に複数のサーバプロセスは同時にデータ変更処理が行えます(ただし同一データを除く)。REDOログの書き出しにおいても、LGWRは複数のサーバプロセスのREDOログをまとめて書き出せるため、高いスループットが実現できます。
-レスポンスを重視
--COMMIT時にREDOログを書き出し、ブロックをディスクに書き出さないことによって、高速なCOMMITを実現しています。
-COMMITされたデータは守る
--仮にDBWRがデータを書き込むまもなく、マシンがハード障害でダウンしたとしても、その後、REDOログとデータファイルに残っている古いデータを使ってデータを復旧させる(ロールフォワードする)ことができます。
ここで「UNDOは表領域に格納されているから、リアルタイムにディスクに書き込まれないんじゃないの?」とするどい突っ込みをする方もいらっしゃるかと思いますが、実はUNDOの更新情報もREDOログに入っているため、ロールフォワードすることによりUNDOも最新の状態になっていくのです。起動時に自動的に行われるこの回復(リカバリ)を、「インスタンスリカバリ」と呼びます。正式には「クラッシュリカバリ」と言いますが、世の中ではインスタンスリカバリと呼ばれることが多いので、ここでもインスタンスリカバリと呼ぶことにします。
第9章のまとめ
-REDOは古いデータを最新にするためにある
-UNDOは新しいデータを古くするためにある
-読み取り一貫性はUNDOを使っている
-ORA-1555が発生する場合には、まず、undo_retentionやUNDO表領域のサイズをチューニングすることを検討する
-マシンがクラッシュしたり、インスタンスが異常終了した場合には、REDOとUNDOを使ってデータの復旧と未COMMITデータのロールバックが行われる
データベース破壊の例
+ディスクの物理的な故障によるデータファイルの消失
+オペレーションミスなどにより、OS上で削除や上書き
+何らかの問題によるブロック破損
+データファイルに対する一時的なアクセス不可
+ハードウェアの物理故障やケーブルの緩み
◆データファイルに対する一時的なアクセス不可
Oracleがデータファイルにアクセスしようとしたとき、OSやストレージ側の都合や不具合でファイルにアクセスできないことがあります。読み込めない場合はエラーになる程度で済みますが、書き込めない場合、Oracleはデータファイルをオフライン(使えない状態)にして、リカバリが必要だと認識します。書き込めない表領域がSYSTEM表領域の場合には、インスタンスがダウンします。
Column RMANって何?
RMAN(「アールマン」と読みます)とはOracle8以降のOracleに標準で付属しているユーティリティ「Recovery Manager」の略称で、バックアップ/リカバリを簡単に行えるGUIの管理ツールです。RMANは、サードパーティ製品とし連動して自動的にテープからのリストアを行ってくれるという機能や、管理情報
をもつカタログデータベースというデータベースを備えることもできます。
最近のRMANは、RMANでしか行えない機能が存在したりもします。10g以降のRMANで筆者が注目に値すると考えているのは、更新した箇所だけのバックアップ機能(チェンジトラッキング)とバックアップしたファイルの更新機能(増分更新バックアップ)です。
こんな感じですかね。図解がメインの本なんでテキストだけでまとめるとよさが全然わかんないかと思いますが、あしからず。