データベースコンサルタントのノウハウちょい見せ

Oracle RDBMSなどのオラクル製品や各種インフラ技術(OS、ストレージ、ネットワーク)といった話題を取り上げます。著者は小田圭二、「門外不出のOracle現場ワザ」、「絵で見てわかるOracleの仕組み」、「絵で見てわかるOS/ストレージ/ネットワーク」などの著作もあります

ホーム > アーカイブ - 2008年12月

サーバー分割の考え方(高可用性やアプリの開発の観点から)

ブログを書くポリシーとして、「週に2回、DBAやインフラ担当者の役に立つ記事を書く」と決めています(当面の間、守れるだけ・・・^^;)。そこで、今回は著書の紹介だけでなく、もう1つ記事を載せます。

●読み取り処理の高可用性と、データ変更処理の高可用性の実現

フリーのDBMSをうまく使って可用性の高いシステムを作っている会社も増えてきました。商用かフリーかに関わらず、可用性の高いシステムを実現するための考え方があります。
それは、レプリケーションの考え方、および、トランザクションスコープの適正化です。mysqlなどで可用性の高いシステムを作る際には、読み取り(read)のデータをレプリケーションで他のサーバーに伝播させ、可用性を高めることがあります。1台停止しても読み取りは成功します。そして業務を続けることができます。このように、読み取りについては、データのコピー(一般にレプリケーション)による冗長化が効果的です。

データ更新処理の高可用性は、読み取りのようにはいきません。同じデータすべてに対して即座にデータ更新を実施する必要があり、1台停止すると、データ更新全体が失敗します。仮に失敗したサーバーのみデータ更新を諦める場合でも、障害/復旧後は、データの同期化が必要です(ダウンしていた時間帯のデータ更新が失われているので)。そういう意味で、データ更新の冗長化は難易度が高いのです。

データ更新は、トランザクションという形で実装されます。そのトランザクションが広い(多くのサーバーやコンポーネントをまたがる)場合、障害に当たる確率、および、他に迷惑をかける可能性が高くなります。そこで、トランザクションスコープが最小限になるようにサーバー分割を行います。他のサーバーへのデータ伝搬はレプリケーションで行います。そうすれば、業務停止は最小限ですし、トランザクションスコープ外のサーバーが停止したとしても、ユーザーは待たされません。サーバーが復旧すればレプリケーションも再開されます。

このように読み取り処理のためにサーバー冗長化(分割)、データ更新のためにサーバー分割という分割の仕方があります。これは、可用性向上のための物理的なサーバー分割です。

●データのまとまりの観点で見た、システムサブ分割としてサーバー分割

前回の記事でも書きましたが、業務全体のデータモデリングを行い、どのデータの範囲をどのシステムが担当するのか、を見定めて分割するという仕方もあります(※)。この分割の方法のメリットは、データの冗長持ちが減ること、および、トータルでのアプリ開発の生産性があがることです。
※:参考となる文献として、「業務別データベース設計のためのデータモデリング入門」渡辺幸三 P132「データモデルとサブシステムの深い関係」 が良いと思います。手島歩三さんや繁野高仁さんも同様のことをよく書いているのですが、お勧めの文献が見つからないので割愛します。

一部の方々は、ERPの導入の評価にも、この「データをベースとした分割やフィットギャップ」という手法を使っています。通常、ERPのフィットギャップといえば、欲しい業務機能をどれだけ網羅しているかという観点になりますが、データをベースとしたフィットギャップについては、どれだけ欲しいデータ(エンティティ)を持っているか、リレーションがどれだけ会社のビジネスモデルに近いか、という観点で評価します。データを持っていれば(データがフィットしていれば)、その上のアプリケーション開発は容易という考え方です。業務アプリケーションでは、データが重要ですから、このような方法も十分あります。

●まとめ

よく見られる、「業務部門の区切りがサブシステムの区切り」や「発注の区切りがサブシステムの区切り」という分割の仕方だけでなく、「インフラの可用性のための分割」という考え方と、「データや業務の観点からのあるべき分割」という2つの考え方もあります。前者は通信制御系やチャネル(止めてはいけない顧客への窓口)といったところに向きます。後者は、データ項目が多く、アプリ開発も大変な業務システム(会計や勘定や顧客データベースなど)に向きます

スポンサーサイト
[ 2008/12/31 01:22 ] アーキテクチャ | TB(0) | CM(0)

著書の紹介

今回は著書の紹介です。新年からの学習にお役立てください。

●「絵で見てわかるOS/ストレージ/ネットワーク データベースはこう使っている 小田圭二 著
私のポリシーである”DBMSもOSの動くアプリケーションに過ぎない”に基づいて、OSとDBMSの関係、ストレージとDBMSの関係、ネットワークとDBMSの関係、を解説した珍しい書籍です。DBを学んでひと段落したら、DB使いもインフラ全体を意識しなければなりませんが、そのような人にお勧めです。エンタープライズ向けのコンピュータ書としてはかなり売れました(最後は出版社談)。

●「絵で見てわかるOracleの仕組み小田圭二 著
教育に携わる者としての私の思い「丸暗記するな。アーキテクチャを知るべき。絵で説明すべき」を具体化した、Oracleの入門書です。Oracle初心者向きですが、Oracleの基礎となる部分の動きを解説しているため、バージョンに依存せずに何年先でも使えます。逆に、本書の内容を理解せずに、ひたすら丸暗記すると応用力が身につきません。この本を読むだけで何かできるようになるわけではありませんが、アーキテクチャを身につけて、本当の技術力を身につける第一歩として欲しいと思っています。


●「門外不出のOracle現場ワザ 小田圭二 他 著
一番最初に出た本です。結構とがった内容を扱っています。
・パフォーマンス分析の考え方(私の担当)
・性能テストや障害テストの仕方、設計の注意点(主に私が執筆)
・コストベースオプティマイザ(10gベース)のアーキテクチャ
・コネクションプーリング
最新のOracleの内容は含んでいませんが、今でも性能の考え方やオプティマイザの考え方は使えるはずです。オプティマイザをここまで解説している本を私は知りません。

●「続・門外不出のOracle現場ワザ小田圭二 他 著
「続」の名前の通り、次に出た本です。ちょっと尖り過ぎたかもしれません^^; でも本当に使う内容を選んだつもりです。一流になりたい・他の人と差をつけたい人にお勧めでしょうか
・性能の良いSQLの書き方
・文字化けの仕組み
・障害(特に性能やハング)の分析・対応方法(私が執筆)
・障害をリアルタイムに分析・対処する方法(私が執筆)
・オプティマイザの使い方ノウハウ
・アップグレードのノウハウ

●「データベース小田圭二 他 著
私にしては堅い本です。なんせ、共同執筆者が大御所の國友義久先生です。階層型DBMS、ネットワーク型DBMS、リレーショナル型DBMS、XMLDBMS、OO(オブジェクト指向)DBMS、DBMSの持つ機能、DBMSのセキュリティ、データベースの著作権、監査、モデリング、正規化といった内容を網羅しており、深い記述は無いものの、DB技術全体を抑えるのに向いている一冊です。ある程度技術力がついたエンジニアの方が、DB全体を振り返りたい(勉強したい)というときの最初の1冊としてお勧めです。

何かを調べるときや学ぶときに、これらの本をご活用いただければ幸いです。
[ 2008/12/31 01:15 ] 雑談 | TB(0) | CM(0)

なぜ、重複するデータがあちこちに蔓延するのか、および、その対策

複数のシステムを持つ会社が増えてきました。当然、データベースも複数存在します。そのデータベース同士を比較すると、重複するデータを持っていることが多くありませんか?

システムをまたがっている場合でも、可能であれば、データの重複は避けるべきです。理由は、メンテナンスとデータの整合性の向上です。たとえば、5つのシステムに別々にデータをもっていると、データメンテナンスが5回になります。また、あるシステムと別のシステムでデータの整合性が合わなくなり、計算が合わなくなることもあります。

「データを1つにする」と簡単に書いていますが、実はいくつかの実現レベルが存在します。一番、イメージしやすいのは、物理的に1つのデータをどこかのデータベースに持たせることです。利用時には、そのデータベースにアクセスすることになります。統合データベースを作るプロジェクトなどが目指す姿です。現実には、複数の業務が同じデータ(たとえば会員ID)を使うことが多いため、統合データベースが無い場合は位置の透過性を実現するDBMSの機能(他のDBのデータを自分のものに見せることができる)を使うことになります。Oracleであればデータベースリンク、DBMSによってはフェデレーションなどと呼ぶ機能のこともあります。
統合データベースの注意点は、可用性がシビアになることでしょう。業務が相乗りすることになるため、止められなくなります。
位置の透過性の注意点は、ひきづられることと、性能でしょう。透過的とは言え、実際には他のDBMSにアクセスするわけで、他のDBが障害になると自分のDBまで影響を受けてしまいます。性能の影響は顕著で、どうしてもネットワーク越しとなり、格段に遅くなることが多いです。意識しないと大変なことになります。

「データを1つにする」のもう1つの実現レベルが、「定義を合わせる」ことです。データディクショナリ(Oracleのデータディクショナリではないですよ)というデータの辞書を作り、各システムで定義(各データの意味)を合わせることです。たとえば、会員IDを1つとっても、桁数は何桁なのか、0詰めするのか、退会した人を含むのか、退会した人を含む場合は過去どれくらい含むのか、どの業務にとっての会員IDなのか(一部の業務とは関係の無い会員IDというのも存在します)などなど、いろいろな定義の違いが存在します(上記は全て実体験に基づいています)。システムをまたがってデータが重複していても、こういった定義が同一であるだけで、ずいぶん扱いやすくなります。実際問題、このレベルの「データを1つにする」ことが最善であることも多いです。

データのオーナーのシステムが決まっていないケースもあります。どっちのシステムのデータを正とすればいいんだっけ?という疑問が浮かぶようであれば、それはデータのオーナーが決まっていないことを意味します。必ずオーナーのデータを更新して、それがコピー側に反映されるようにしましょう。

「データを1つにする」の最後の1つの実現レベルが、「定義を合わせ、かつ、データは多重持ちしつつ、自動的に連携する」ものです。MDM(マスターデータマネージメント)やHubなどと呼ぶようですが、データ連携の基盤や製品を使って、自動的に連携させる方法です。各システムに実データが置いてあるため、性能も良好ですし、自動的に連携するのでメンテナンスも比較的容易です。難を言うと、導入が大変なことでしょうか。システムが増えると、このような仕組みが必要になってきます。

ちょっと見方を変えてみます。なぜ、データの重複が増えるのでしょうか? まず、各システムが個別最適になっていることが挙げられます。SIerがシステムを作る場合、そのシステムに必要なデータ項目は洗い出しますが、それが他のシステム(特に他のSIerが作ったシステム)と被るかどうか、連携をとるべきかどうか、などは考えません。すると、会員IDのような、どのシステムでも使われるようなデータ項目は、各システムごとに持たれてしまいます。

「どの業務をどのシステムが担当するのか」が整理されていないこともデータの重複を増やす原因の1つです。なんとなく、つぎはぎで開発して、不格好になっているシステムが多いです。きちんとデータの区切りごとにシステム分割すれば、重複は最小限になります。概念データモデリングを行い、会社の持つデータを明らかにし、どのシステムがどのデータを持つべきかを考えて、システム分割する方法です。これは情シス側が行うべきデータモデリングと言えます。理由は、「システム横断的に実施すること(SIer1社ではないこと)」「SIerに対して、このデータ範囲をシステム化してくれといった、SIerマネジメント/チェックのために使えること」です。

まとめると
・物理的に1つに統合するのも手
・データディクショナリなどを使って、定義を共通化するのも手
・データ連携の基盤を作るのも手
・同じデータが重複して存在する場合でも、データのオーナー(正)は決めよう
・概念データモデリングなどを用いて、システム分割を考え、重複を抑えよう
です。

データの重複を抑えるのは、簡単ではありませんが、コントロールされていない重複データの増殖はボディーブローのように現場の手足を縛っていきます。「データをきれいにする」ことにもこだわりましょう!
[ 2008/12/26 15:26 ] アーキテクチャ | TB(0) | CM(0)

情報の特性と、第一人者になる方法、Oracle雑学

●はじめに
矢木さんから面白い(でもちょっと高度な)質問をいただいたので
回答してみました。RACのアーキテクチャの記事も良いので、もしよければ見てみてください。

Oracle雑学は、最後のパートです。

●どうやればエキスパートになれるのか?
若手から「どうすればエキスパートになれるか?」という趣旨の質問を忘年会でもらったので、今回はそれを書いてみたいと思います。

タイトルにある「情報」というのは、コンピュータの扱う情報(データ)のことではありません。人から人へ伝わる情報のことです。「情報は出す人のところに集まる」という習性があるという話です。それを生かして、どうやったら初心者がエキスパートや第一人者になるのか・・・を少し説明します。

プロフィールのところにも書いていますが、元々、私は人事に所属していました。当時は数百人という新卒を教えていました。彼ら彼女らのその後もある程度把握しています。また自分自身も、新卒からいきなり人事所属の先生へ。その後コンサルへというチャレンジをしていますので、この分野についてはある程度のノウハウを持っているつもりです。

まず、一番お勧めしないのが、ひたすら読んで丸暗記です。人は忘れる生き物です。新人研修でも丸暗記させたものは、その後、仕事であまり役に立っていませんでしたね。例外は文法でしょうか。SQLの文法は丸暗記(というか、ひたすら実践)が効果的でした。

覚えるためには、「使う」ことが必要です。テストを受けることで、「知識を使う」こともできますが、どうしても本業や仕事で使うことと比べると、劣ってしまいます。

私の場合は、コンサルとして、他のコンサルに情報を出します。そうすると、次から次への同様のテーマの情報が集まったり、質問が集まります。すると、自然と第一人者になるという方法です。これが、「情報は出す人のところに集まる」という習性です。

でも、ここで初心者にはジレンマが待っています。知識を持っていない、仕事で使う機会がない、情報を出す機会がない、知識が手に入らない、座学する程度・・・の悪循環です。

そういう人には、まず「宣言する」ことをお勧めします。「私はXXの達人(エキスパート)です」と宣言してしまうのです。すると、質問が集まります。その質問を調べてでも良いので答えます。そうやっていくとあら不思議、いつのまにか第一人者・エキスパートになれるんです。そうやって、私は、Oracleコンサルの中で「OS、ストレージ、ネットワーク」に詳しい人という地位を築いてきました。

質問を受けたり、知識を使ったりする機会が無いという方は、まずアウトプットの場を作ることをお勧めします。メーリングリストでも、良いドキュメントをどこかのサイトにアップするでも、ブログに記事を書くでも、なんでも良いと思います。
#皆さんも気がついたと思いますが、このブログにはこういう目的もあります^^;

アウトプットを意識することは勉強の効率が上がることも意味します。期限が切られているとさらにグッドです。

さて、ついやってしまいがちな知識の身につけ方が、「できるだけ早く勉強を始めてしまうこと」です。早く始めるのは当たり前、と思うかもしれませんが、これは違うと思います。CCPMの書籍の中でも書かれているように、できるだけ遅く始めた方が良いと思います。早く始めると使うことには忘れてしまうんですね。効果が薄れます。「学ぶ&使う」の原則を考えると、できるだけ遅く学び始めるのがベストです。

まとめると、
「情報を出すことで、逆に学ぶ」
「初心者は、XXXのエキスパートだと宣言する」
「アウトプットを用意する・アウトプットを意識して学ぶ」
「使う直前に学ぶ(できるだけ遅く学ぶ)」

です。

●Oracle雑学

なんか、インフラやDBから離れているよな・・と思ったので、ちょっと雑学です。

データベースの語源は? データ(data)の基地(base)というのが1つの説です。軍事絡みだったとか。

Oracleの有名なユーザーIDである scott/tiger の由来は? 実は、scottさんは昔々のOracleの開発者です。で、その方が飼っていたネコが tiger という説が最有力です。scott/tigerを本番データベースのユーザーIDに使っているシステムがあるとかないとか・・・

[ 2008/12/24 01:03 ] スキル強化・教育 | TB(0) | CM(0)

ネタ(アンチパターン)募集

数か月先のDBマガジンに「データベースのアンチパターン(続編)」の特集を書くことになりました。私の中では「アンチパターン(良く見るダメな設計)」のネタは十分にあるのですが、せっかくブログを書いているので皆様からもネタを募集したい(活性化したい)と思います。なお、ネタ(項目)だけであって、中身は私の考えで書いてしまいますので、その点はご了承ください。

☆現時点の案(ネタの余地は、あと3,4個くらいでしょうか)
OLTPなのにSQLが重い
キャパシティが見積もれていない
領域監視をしていない
DBリンク地獄
バッチがリランできない
外部キーに索引をつけていない
バッチで適切に処理を分割していない
トランザクションスコープが不適切
再利用しない(コネクションなど)  ・・作っては捨てる
バインド変数を使っていないSQL
不適切なリトライの仕組み
リソースのバランスが悪い
詰まると接続が増えるアーキテクチャ
ひきづられるアーキテクチャ
性能分析できない(タイムスタンプつきのログが取れない)

☆前回の特集の項目
インデックスがついていない
インデックスが多すぎて性能劣化
結合条件のつけ忘れにより直積処理が発生
結合する表が多すぎる
パズルかのようなSQLで性能が出ない
ビューを多用して性能がでない
RDBMSをデータ格納のための1つの大きな箱としか見ない
列が多すぎる表
使われているかどうかわからない表が残っている
外部からの監視や正常動作の監視が抜けている
データベースのメンテナンス(再構成など)をしていない
リカバリできない
通信相手の生き死に確認は難しい
サービスに問題が無いか判断できない(クラスタソフト任せには限界あり)

上記に含まれない「良く見るダメな設計」の心当たりがあれば、ぜひ、コメントに入れていただけばと思います。よろしくお願いします!
[ 2008/12/18 13:53 ] DBA | TB(0) | CM(12)

コンサルティングを受ける際の必要条件、コンサルタントのあるべき姿

今回は、私見ですが、知っているようで知らないコンサルティングを受ける際の必要条件や、コンサルタントのあるべき姿についてです。

システム構築の上流エンジニアをコンサルタントと呼ぶこともありますが、そういったコンサルタントではなく、少人数で活動する、お客様の相談にのることを主業務とするコンサルタントのことをここでは”コンサルタント”と呼んでいます。

当たり前ですが、「コンサルタント != 作業者」 です。簡単に言うと、コンサルタントは知恵とノウハウを渡してくれる人であるべきであり、単価が高いけれども、品質の高いアウトプットを作る作業者(エンジニアなど)ではあってはいけません。・・・というのが私の持論です。

知恵やノウハウを出す・・・のであれば、それを活用する受け皿が必要です。その受け皿を用意していない現場が実は多々見られます。その場合、実はコンサルを雇うよりも、経験を積んだSEやマネージャを雇うべきだったりします。コンサルタントだけで結果を出すものではないため、コンサルタントを悪く言えば、「言いっぱなし。資料を出しっぱなしの人」です。ということで、コンサルを活かせる現場かどうか(受け皿があるかどうか)というのは大事です。
また、結果が出ないということをコンサルに怒るのではなく、「良い知恵やノウハウを出さないと怒るべき」ということです。異論はあるかと思いますが、これがコンサルと現場のあるべき姿だと思います。

実際、以前、現場に受け皿となる人材がいないため、コンサルタントをスーパーエンジニアとして扱おうとしていた(「作業もしてね!」という依頼をしてきた)現場がありましたが、うまくはいきませんでした。単価も高いですしね。

コンサルタントには、プロとして、第3者としての意見も求められます。言いにくいことを言わなきゃいけないときもあります。現場の思いは汲んであげる必要はありますが、現場に流されて悪いところを”悪い”と言えなくなってくると、その現場に長く居すぎたな・・・と思ってしまいます。

コンサルタントは、自分から活動することも大事で、受け身だと「言われたものを作る作業者」になっちゃいます。これでは、やはり価値を認めてもらえないです。このパターンはSEから転職したてのITコンサルタントに多いです。

私が思う、コンサルタントになるための必須条件は「何らかの業務に対して、こうあるべきだという熱い思いを持っていること」です。これがないと、自分から働きかけることができず、お客様からの依頼に従って、受け身で作業することになってしまいます。プロとして、第3者として、自信を持って「こうすべき」とも言えないです。

このブログを読んでいる人の中には、コンサルタントになりたい人も居るかと思います。よく、「コンサルスキルは大事だ!」といいますが、コンサルタントになるには、コンサルスキルを身につける前に、「何らかの業務に対して、こうあるべきだという熱い思いを持つこと」を私はお勧めしています。語るべき内容を持たずに、トーク(道具)だけ充実させてもしょうがないですよね?

最近は、「コンサルタント」ばやりのため、なんでも「XXXXコンサルタント」という名前が付いているのも事実です。言ってしまったもの勝ちの感がありますが、少なくともその分野については、語るべき内容を持っていたい・・・と私自身を振り返って思っています。
[ 2008/12/18 13:51 ] コンサル手法 | TB(0) | CM(0)

気になる隣のプロジェクト:みんなパッチを当ててるの?

みんな気になる、他所のプロジェクトの実態の紹介です。良いかどうかはここでは議論しません。みんなパッチをあてているのしょうか? 特にセキュリティパッチをあてているのでしょうか?というネタと少しでも適用しやすくなるTIPSです。

●セキュリティパッチは当ててるの?

実はいくつか調査結果があります。例:
「Oracleの最新セキュリティ・パッチを適用したデータベース管理者は1割」,Sentrigoの調査

この記事を見てもわかるように、皆さん、パッチを当ててません。どういう根拠でセキュリティパッチを当てないのでしょうか? お客様から聞くのが「ファイアウォールの後ろにあるから」というものです。通常、DBサーバーはファイアウォールの後ろに置きます。とすると、セキュリティパッチで扱うような脆弱性の攻撃はそもそもファイアウォールでカットされているよね? という理屈です。
#ネットワークの設計の定石として、APサーバーおよびDBサーバーはファイアウォールの後ろが安全です。

ただし、最近のセキュリティベンダーのアセスメントレポートや指導などから読み取ると、「ファイアウォールの後ろにあるからセキュリティパッチは当てなくて良い・・は古い」となりつつあります。将来はこの手は通用しないかもしれません。

#なお、貴社のセキュリティポリシーと照らし合わせて、くれぐれもきちんとした判断をしてください。本ブログの情報を信じて、判断の手順を省略するのはダメですよ。

●集積パッチ(Oracleでいう”PSR”)は?

さて、次に、みんな集積パッチ(PSR)はあてているのでしょうか?
まず実プロジェクトで見られる実例の傾向として言えるのが、クライアント側の集積パッチ(PSR)を当てないケースが多いことです。これはクライアント側にはシビアなバグの数が少ないため、なんとなく納得できます。

サーバー側の集積パッチはどうでしょうか? これを障害にあたる前に当ててくれているお客様は、まま見られます。でも現実は・・・って感じです。

事前に当てない理由として多いのはなんでしょうか?
「安定しているから(障害に当たらないから)」
「このPSRでテストをしたから(PSR当てたらもう一度テスト? 勘弁してよ・・・)」
「パッケージ製品が指定しているPSRがこれだから」
といった理由をよく耳にします。

実際、現場はカツカツの状態ですし、PSRを当てるとしても業務APも含めたテストをするのは大変です。事前に当てた方が良いと頭では理解しつつ、”無い袖は振れない”という事情で当てていないのが実情だと思います。

そこで、ちょっとは役に立つであろう「コストを抑えながら、PSRを適用するノウハウ」の紹介です。前提として、何らかの追加開発を行うことが決まっているとします。その開発の環境に新しいPSRを適用します。追加開発の一環として、性能テストもするでしょうし、既存APの機能テストもするでしょう。それをもって「PSRのテストも行った」という扱いにする方法です。これであれば、PSRのためだけに開発者にテストしてもらわなくても、ある程度は網羅的にテストが行われます。この方法でOKとするかどうかは、会社のポリシーもあるかと思いますが、この方法は1つの現実解だと思います。PSR適用のためだけに、開発者にテストをしてもらうのは、現実問題として困難ですよね。

●まずは・・!

まずは”バージョンアップや集積パッチあての予算をつけて! 運用に回る予算が少なすぎ!”というのが私個人から情シスのマネージャへのお願いです。予算がつけば現状が少しは変わると思うためです。

次は、年間計画の中に、パッチあてを組み込みましょう。事情により適用できないこともあるでしょうが、計画した数回に1回適用できれば、それだけでもずいぶん違うはずです。

それと・・・、最後は現場の皆さんが鍵を握ります。パッチ当てましょう!

[ 2008/12/15 02:22 ] DBA | TB(0) | CM(1)

SQLのシーケンシャルアクセスと実I/Oとしてのシーケンシャルアクセス

今回は、一部の人には「驚愕の事実」(らしい)、SQLのシーケンシャルアクセスと実I/Oとしてのシーケンシャルアクセスが異なる(ことがある)という話です。

何回か前の記事に、『OTNの記事を読みました。待機イベント名の「sequential(シーケンシャル)」は実質的にはランダムI/O・・・が衝撃的でした』とコメントをいただきました。確かに誤解している人が多い事実です。解説についてはこちら(リプライコメント)を御覧ください。

そのコメントを読んでいて、もっと多くの人が誤解している、ちょっとマニアックなOracleの動作があることを思い出しました。それは、SQL上ではシーケンシャルアクセス(フルスキャン)となっていながら、実I/Oではランダムアクセスが発生することがあるという事実です。<- 驚愕の事実?

この記事は、その仕組みの解説と検証による証明を載せています。本記事は「仕組みをしりたい」もしくは「コンサルの検証ノウハウの一端を見たい」という方に向いていると思います。

●仕組みの解説

昔のDBMSと比べ、Oracleはキャッシュを強く意識しています。キャッシュを前提としたアーキテクチャになっている断言しても良いと私は思います。ここで仮に、あるテーブルが4ブロックで構成されていて、その4ブロックのうち3ブロックがキャッシュに載っているとします。そのような状況でテーブルをフルスキャンするSQLが実行されたとします。すると、3ブロックが載っていますから、残りの1ブロックをランダムアクセスで読み込む・・・という動作をOracleはします

4ブロック中の2ブロックがキャッシュに存在し、キャッシュに載っていないブロックがディスク上で連続しているとします。その場合、その2ブロックだけを読み取るシーケンシャルアクセスをOracleは行います。SQLの実行計画がシーケンシャルアクセスであっても、キャッシュに存在しないデータだけを実I/Oで読みこむということです。

●検証

多少、省いているログもありますが、実際に試したところ次のような結果となりました。コンサルの検証テクニックとともに、ご確認ください。

☆確認したいこと
・キャッシュに載っていないときは、実I/Oも全ブロックをシーケンシャルアクセスをしている
・キャッシュにある程度載っていて、載っていないブロックがディスク上連続して存在している場合には、載っていないブロックだけシーケンシャルアクセスする
・キャッシュにほとんどのブロックが載っていて、1ブロックだけディスク上に残っている場合には、そのブロックだけランダムアクセスする

☆テクニック
・ある行が、どのブロックに存在しているのか確認する
・該当ブロックがキャッシュに載っているか確認する
・バッファキャッシュをフラッシュするコマンド
・待機イベントの履歴から、シーケンシャルアクセスかどうか、シーケンシャルアクセスの場合には、どのブロックを、何ブロック連続で読み込んだか確認する


☆準備(テーブル作成とデータ増殖)

SQL> create table test (no number, text varchar2(100));

表が作成されました。

SQL> create index test_index on test (no);

索引が作成されました。

SQL>
SQL> insert into test values(1,'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');

1行が作成されました。

SQL>
SQL>
SQL> insert into test select no+1, text from test;

1行が作成されました。

SQL> insert into test select no+2, text from test;

2行が作成されました。

・・・・

SQL> insert into test select no+128, text from test;

128行が作成されました。

#test表自身のデータを活用して、test表のデータを倍々に増やすやり方です。
#この増殖のさせ方は楽ですよ。

次の表の先頭行と後方の行が、どのファイル、どのブロックに存在するかを確認します。ご存知の方も多いと思いますが、DBMS_ROWIDというパッケージで調査できます。

SQL> select DBMS_ROWID.ROWID_RELATIVE_FNO (rowid),
2 DBMS_ROWID.ROWID_BLOCK_NUMBER (rowid),
3 DBMS_ROWID.ROWID_ROW_NUMBER (rowid)
4 from test where no = 1;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)
----------------------------------
1 87986
0


SQL>
SQL> select DBMS_ROWID.ROWID_RELATIVE_FNO (rowid),
2 DBMS_ROWID.ROWID_BLOCK_NUMBER (rowid),
3 DBMS_ROWID.ROWID_ROW_NUMBER (rowid)
4 from test where no = 255;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)
----------------------------------
1 87989
56

このテーブルの行は、ファイル番号:1の、ブロック番号が87986から87989の間に含まれていることが分かりました。

統計情報の取得などを行った上で、いったんバッファキャッシュから消えてもらいます。実は、最近のOracleであれば、「alter system flush buffer_cache」というコマンドが使えます。

SQL> alter system flush buffer_cache;

システムが変更されました。

SQL> select file#, block#, status from v$bh where file# = 1 and block# between 8
7986 and 87989 order by block#;

FILE# BLOCK# STATUS
---------- ---------- ----------
1 87986 free
1 87987 free
1 87987 free
1 87987 free
1 87987 free
1 87987 free
1 87988 free
1 87989 free
1 87989 free

このv$bhというビューは、バッファキャッシュの状況を確認することができます。freeという状態は、キャッシュに載っていないということを意味します。このv$bhは検証のときに重宝します。

次に、SQL*PlusのSID(セッションID)を特定します。これはあとで、具体的なI/Oを確認するためにSIDが必要となるためです。SYS_CONTEXT関数で、自分自身のセッションの情報を取ることができます。

SQL> SELECT SYS_CONTEXT('USERENV','SESSIONID') AUDSID from dual;

AUDSID
--------------------------------------------------------------------------------

80096

SQL> select sid from v$session where audsid = 80096;

SID
----------
122


SIDが122だと判明しました。

☆キャッシュにブロックが無いケース

test表をフルスキャンします。その後、SIDが122のセッションの過去10個の待機イベントを調べます。待機イベントからシーケンシャルアクセスかどうか、連続ブロック数はいくつなのか、読み込んでいるブロックはどれなのかを確認できます。

SQL> select sid, event, p1,p2,p3, time_since_last_wait_micro from v$session_wait
_history where sid = 122;

SID EVENT
---------- ----------------------------------------------------------------
P1 P2 P3 TIME_SINCE_LAST_WAIT_MICRO
---------- ---------- ---------- --------------------------
122 SQL*Net message to client
1111838976 1 0 27

122 SQL*Net message from client
1111838976 1 0 91

122 SQL*Net message to client
1111838976 1 0 582

122 db file scattered read
1 87986 4 552

122 db file sequential read
1 87985 1 79

122 db file sequential read
1 87993 1 670

122 SQL*Net message from client
1111838976 1 0 6

「db file scattered read」は、OracleのシーケンシャルアクセスのI/Oです。P1がファイル番号、P2がブロックアドレスです。P3がブロック数です。1 と 87986 で 4 となっているため、test表全体を1回のシーケンシャルアクセスで読み込んでいます。

☆キャッシュに一部のブロックが載っているケース

4ブロックのうち、最初と最後のブロックのみキャッシュに載せます。

SQL> select /*+ index(test,test_index) */ * from test where no = 1;
SQL> select /*+ index(test,test_index) */ * from test where no = 255;

SQL> select file#, block#, status from v$bh where file# = 1 and block# between 8
7986 and 87989 order by block#;

FILE# BLOCK# STATUS
---------- ---------- ----------
1 87986 xcur
1 87986 free
1 87986 free
1 87987 free
1 87987 free
1 87987 free
1 87987 free
1 87987 free
1 87988 free
1 87988 free
1 87989 xcur
1 87989 free
1 87989 free
1 87989 free

14行が選択されました。

xcurという状態は、キャッシュに載っていることを示します(一種の状態)。

87987 と 87988 はキャッシュに載っていません。この状態でフルスキャンを実行します。待機イベントを確認します。

SQL> select sid, event, p1,p2,p3, time_since_last_wait_micro from v$session_wait
_history where sid = 122;

SID EVENT
---------- ----------------------------------------------------------------
P1 P2 P3 TIME_SINCE_LAST_WAIT_MICRO
---------- ---------- ---------- --------------------------
122 SQL*Net message to client
1111838976 1 0 31

122 SQL*Net message from client
1111838976 1 0 131

122 db file scattered read
1 87987 2 196

122 db file sequential read
1 87985 1 52

説明したように、載っていないブロックのみ、シーケンシャルアクセスで
読み込んでいます。db file scattered read のP2とP3が、
87987 と 2 となっています。


☆キャッシュにほとんどのブロックが載っているケース

select /*+ index(test,test_index) */ * from test where no = 1;
select /*+ index(test,test_index) */ * from test where no = 128;
select /*+ index(test,test_index) */ * from test where no = 255;

SQL> select file#, block#, status from v$bh where file# = 1 and block# between 8
7986 and 87989 order by block#;

FILE# BLOCK# STATUS
---------- ---------- ----------
1 87986 free
1 87986 xcur
1 87987 free
1 87987 xcur
1 87987 free
1 87987 free
1 87987 free
1 87988 free
1 87989 free
1 87989 xcur

10行が選択されました。

87988のみキャッシュに載っていません。フルスキャンを実行します。待機イベントを確認します。

SQL> select sid, event, p1,p2,p3, time_since_last_wait_micro from v$session_wait
_history where sid = 122;

SID EVENT
---------- ----------------------------------------------------------------
P1 P2 P3 TIME_SINCE_LAST_WAIT_MICRO
---------- ---------- ---------- --------------------------
122 SQL*Net message to client
1111838976 1 0 29

122 SQL*Net message from client
1111838976 1 0 108

122 db file sequential read
1 87988 1 170

122 db file sequential read
1 87985 1 51

待機イベントが、db file sequential read (ランダムアクセス)に変化しました! ブロックのアドレスも87988となっていて、きちんと載っていないブロックだけを読み込んでいます。

●まとめ

いかにOracleがキャッシュを有効活用(重要視)しているかという証拠だと思います。実行計画だけで実I/Oが決まるわけではない(キャッシュの状態に依存する)ことがお分かりいただけたかと思います。

●その他

SQL Developerのデータモデリング機能(Early Access版)が更新されました。興味のある方はこのURLへ。Oracle SQL Developer Data Modeling 。SQL Developerのデータモデリング機能の記事はこちら。Oracle SQL Developer Data Modelingのblog記事

[ 2008/12/10 23:37 ] DBA | TB(0) | CM(8)

DBMSは何故、手間がかかる? その2

前回の「DBMSは何故、手間がかかるのか?」の続きです。前回を要約すると、「DB(特にRDBMS)はプログラムから独立してデータを管理することを目的としていた。だからDBMSがいろいろとDB内を管理する必要が出てきて、DBの運用は手間がかかってしまう・・・と私は思う」でした。

実は、SQLの性能が安定しないのも、性能管理に手間がかかるのも、同じ理由”プログラムからDBが独立しているからだ”と私は思います。

プログラムの場合、アルゴリズムや動作を変えるのは、プログラマのお仕事です。たとえば、なんらかのデータ長を変更するようなものも、プログラムの中に書きますし、処理アルゴリズムはプログラマの責任です。

それに対して「アルゴリズムを書かない」というのがSQLの言語としての最大の特徴だと私は思います。欲しいデータの”条件”を記述するという言語です。データをプログラムから独立させたRDBMSならではの言語です。

SQLのメリットの1つは、プログラマーが処理の制御を考えていたら、いつまで経ってもかけないような難しい処理を容易に記述することができることだと思います。

デメリットは、処理の制御を意識しなくてよいため、性能が悪いSQLを書きがち、ということと、使用アルゴリズムがDBMSに任されているため、性能変動が起こることです。

性能変動を防ぐ1つのコツは、大量データを使ってSQLの処理をさせて性能を調査し、そのSQLの実行計画で固定することだと思います。大量データで性能をクリアできるのであれば、少量データでも性能をクリアすることができます。下手に少量データで最適な実行計画を選ばせてしまうと、大量データのときに性能が出ない実行計画かもしれません。

実際に現場でみることがあるのですが、少量データで性能テストをして、その実行計画で固定してしまって、大量データの際に性能が出ず、苦しんでいることがあります。少量データではフルスキャンが比較的有利ですが、大量データではインデックスが比較的有利だからです。
#数行から数十行程度の表を考えてみてください。1ブロックに全データを格納できるため、インデックスなどを使ってアクセスする方が時間やCPUを余計に使ってしまいます。

この話から分かる通り、少量データ時点(スタート時点)で最適な実行計画をそのまま使っていれば良い・・・というものでもありません。どうしても「将来も含めて性能劣化させたくない」のであれば、将来を見越した大量データを用いたテストをして、その実行計画を使い続けるのがお勧めです。劣化を防ぐのであれば、少量データ時には多少効率が悪いかもしれない、大量データ時点での実行計画を最初から用いた方が良いという考え(割り切り)です。

もちろん、大量データを作るのは大変です。でも、プログラマがアルゴリズムを考えなくて良いSQLでは、どうしても必要な作業なのです。以前も書いたように、最適な実行計画というのは試してみるまで分からないのですから。

[ 2008/12/08 02:02 ] DBA | TB(0) | CM(2)

DBMSは何故、手間がかかるのか?

最近、DBMSの標準化(パラメータや物理設計の指針を決めて、品質を向上する活動のこと)を検討している際、「なぜ、APサーバーの標準化とDBサーバーの標準化は性格が違うの? なぜDBMSは手間がかかるの?」と聞かれました。その方は、DBMSもAPサーバーもミドルウェアなのだから、APサーバーとDBMSは同じようなものだと思ったようです。さて、皆さんならどう答えますか?

何人かの答えを総合すると、「APサーバーで品質をあげたい(≒トラブルを防止したい)場合は、その上で動くアプリケーションプログラムの品質を上げた方が効果的。APサーバーは運用で行うことは少ないため、稼働後、落ち着いたら手間はかからない。それに対してDBサーバーは設定できることやコマンドが多く、大変だから」という答えが多かったです。なぜ、このような違いが生まれるのでしょうか?

異論はあるかと思いますが、「DBMSはプログラマの管理から独立しているから」というのが私なりの答えです。

ちょっと遠回りして、考えてみたいと思います。C言語では動的にメモリを確保したら、解放することまで含めてプログラムの責任でした。解放ミスがどうしても発生するため、メモリリークが絶えませんでした。そんな中、Javaのガーベジコレクションは画期的でした。プログラマが書かなくても自動的に解放してくれるのです(※)。ただし、その代り、Java VMのチューニングという設定が増えてしまいました。これは、「プログラマが楽をする⇒その代わりの機能が必要となる。また、その機能を制御するための設定が必要となる」ということを意味していると思います。
※:参照の種類の細かい話は割愛します。

元々、DBはデータをプログラムから独立させることが目的でした。当然、プログラムが制御できない箇所が山のように出てきます。データを独立させた以上、DBMSが管理するしかありません。そのため、柔軟に管理できるようにするには、DBMSの機能と設定を豊富にするしかない!・・ということになります。

つまり、上述の「DBMSはプログラマの管理から独立しているから」の背景には、「データをプログラムから独立させたから」という事情がある、という私の見解です。

納得いかない方は、オブジェクト指向DBMS(OODBMS)をイメージしていただくと分かりやすいかもしれません。OODBMSでは、オブジェクトをDBに直接格納するため、プログラムがデータを制御しやすいと言えます。しかし、オブジェクト指向DBMSは基本的にプログラム言語依存です。SQLを持つRDBMSほどプログラムからデータが独立できていないと言えると私は思います。

プログラマの管理から独立しているから、「DBMSは手間がかかる」と思うのですが、いかがでしょうか? 「だからDBMSの運用にコスト(or 人手)がかかることを予め予定しておいてね」と言いたいのです。はい。

良い面もあります。APの標準化(含む「フレームワークを1つにする」)は、パッケージソフトなどのことを考えると、難しいです(パッケージソフトのソースコードは当然いじれませんから)。それに比べると、APから可能な限り独立しているDBMSの標準化はインフラチーム主導で実施する余地があって、設定や設計項目も多いため、DBMSの標準化は効果的です!

[ 2008/12/04 02:15 ] DBA | TB(0) | CM(0)

会社近所の豆屋さん 「但馬屋」

会社のオフィスの近所の老舗の豆屋さんです(オフィスを出て数十秒)。
日本オラクルのオフィス(外苑前駅)にいらっしゃった際には、立ち寄ってみてください。
豆好きの方にはお勧めです。

ホームページはこちら但馬屋
名物はいろいろあるようですが、豆菓子はおいしかったです♪
ピーナッツペーストは、全国お取り寄せランキング1位だとか、、、、
[ 2008/12/01 01:16 ] 雑談 | TB(0) | CM(0)

システムのフロントで処理するということ

珍しく、システムアーキテクチャの話をしたいと思います。

IT Proに「イベント処理システム」の記事が載っていました。
http://itpro.nikkeibp.co.jp/article/OPINION/20081125/319889/
※イベント処理とは、イベント(例:注文が発生など)を契機に処理を発動する仕組みです。

この記事を見て、インメモリDBMSの発想と被るなあと思いました。私は、全部くくって「フロントで返すアーキテクチャ」と呼んでいるのですが、DBMSまで処理を届かせずに高速に処理を行うシステム形態の1つです。
通常のシステムでは、ブラウザからWebサーバー、APサーバーを経由して、DBMSまで処理が届くトランザクションとなります。つまり、バックエンドであるDBMSまでリクエストが届いてしまいます。当然、処理は重いです。

しかし、リバースプロキシ(※)やインメモリDBMSをフロントに置き、可能なものはそこでリクエストを処理してしまうという発想があります
これはイベント処理やトリガー起動、APサーバーのメモリにキャッシュなどの形で実現させます。そして、フロントで処理できない場合のみ、バックエンドに処理を流すという形です。これを私は「フロントで返すアーキテクチャ」と呼んでいます。
※Webサーバーとインターネットの間に置くプロキシ(Webのキャッシュなど)です。セキュリティ強化とキャッシュによる処理の高速化が狙えます。

なお、インメモリDBMSを使う場合、データ保障のためバックエンドに通常のDBMSを用意するのがお勧めです。インメモリDBMSは速いですが、メモリ内のデータは揮発性であるため、障害時に消えてしまう恐れがあるからです(インメモリDBのクラスタリングでデータ保障という手もアリです)。

イベント処理などの「フロントで返すアーキテクチャ」を駆使すると、アーキテクチャの幅が広がると思います。今までは処理量が増えると、DBMSがネックとなってどうしようもなくなっていたシステムでも、これならフロント部分の強化でしのげるかもしれません。また、「フロントで返すアーキテクチャ」は、リレーショナルDBMSの性能でお困りの場合にも使えます(APとRDBMSの間にキャッシュとして入れて高速化を狙うケースです。速くなるかどうかは要件しだいです)。

DB屋さんや、アーキテクトの方には、覚えておいていただきたいのですが、同じようなSQLや問い合わせが繰り返されるシステムの場合(通信業界や金融業界に多いです)、インメモリDBMSやイベント処理をうまく使うと大抵は必要最小限まで劇的に負荷を下げることができます。現在のシステムの性能でお困りの場合、もしくは、いままで「DBMSでは無理だなあ」と思って諦めていたシステムの構築の際に考えてみてください。

なお、例としてOracle社の製品と使いどころを挙げると次のようになります。

Oracle Coherence はインメモリDBMSです。イベント処理機能を持ち、オブジェクト指向であり、かつ、グリッド的に処理を分散させることもできます。データを分散配置させ、複数マシンで同時に処理させることが得意です。上記IT proの記事に一番近い製品だと思います。
Oracle Times Ten もインメモリDBMSです。RDBMSとの親和性が売りです。多くのOracle SQL言語の文法を理解します(対応していない文法もあります)。RDBMSの前のフロントキャッシュとして使うケースが多いです。Times Tenもイベント処理機能も持っているため、工夫しだいでは劇的に高速化できます。

ある方が言っていたのですが、「枯れた製品で枯れたシステムを作るのも良いが、我々は夢を追いかけるのだ。我々の価値は、(障害をおそれずに)新しい価値を実現することだ」という考え方もあると思います。ぜひチャレンジしてみてください。
[ 2008/12/01 01:11 ] アーキテクチャ | TB(0) | CM(0)
プロフィール

odakeiji

Author:odakeiji
小田圭二 日本オラクルのテクノロジーソリューションコンサルティング統括本部においてデータベースのコンサルタントをしている。今までのキャリアでは、社内教育部隊で、データベースやOS、ネットワークを教える経験を5年ほど積んだり、コンサル部門で主にDB(インフラ含む)のコンサルを10年程度経験した。また、コンサルタントとして、主に大規模ミッションクリティカルシステムを担当。社内では”火消し”とも呼ばれ、システムトラブルの火消しをいくつも担当していたこともある。
ポリシーは、「OracleもOS上で動くアプリケーションにすぎない。だから、OS、ストレージ、ネットワークを学ぶべき。アーキテクチャから考えろ」。
スキル面の興味は、アーキテクチャ、DBA、インフラ技術、教育、コンサル手法など。
本ブログのポリシーは「週に1回、DBAやインフラ担当者の役に立つ記事を書きたい」です(守れるだけ、守りたい・・・・)
なお、本ブログにおいて示されている見解は、私自身の見解であって、オラクルの見解を必ずしも反映したものではありません。ご了承ください。

私の主な著書の紹介です。もしよかったら、お役立てください。他にもオライリーなどがあります

●「絵で見てわかるOS/ストレージ/ネットワーク データベースはこう使っている」小田圭二 著
私のポリシーである”DBMSもOSの動くアプリケーションに過ぎない”に基づいて、OSとDBMSの関係、ストレージとDBMSの関係、ネットワークとDBMSの関係、を解説した珍しい書籍です。DBを学んでひと段落したら、DB使いもインフラ全体を意識しなければなりませんが、そのような人にお勧めです。企業ユーザー向けのIT本としては、2008年度翔泳社No1だとか(最後は出版社談)。

●「絵で見てわかるOracleの仕組み」 小田圭二 著
教育に携わる者としての私の思い「丸暗記するな。アーキテクチャを知るべき。絵で説明すべき」を具体化した、Oracleの入門書です。Oracle初心者向きですが、Oracleの基礎となる部分の動きを解説しているため、バージョンに依存せずに何年先でも使えます。逆に、本書の内容を理解せずに、ひたすら丸暗記すると応用力が身につきません。この本を読むだけで何かできるようになるわけではありませんが、アーキテクチャを身につけて、本当の技術力を身につける第一歩として欲しいと思っています。

●「44のアンチパターンに学ぶDBシステム」 小田圭二 著
本書は、企業のDBシステムの設計/構築から運用管理、プロジェクト管理までの各フェーズにおけるトラブル(失敗)事例について、アンチパターン(べからず集)とその回避策/防止策として解説するものです。チェックリストとして使っていただいても構いません。分かっていてもアンチパターンは避けられないことも多いものです(政治とか)。そういう方には、同じ仲間は多いのだなと再認識していただくための一服の清涼剤としていただければと思います。

●「門外不出のOracle現場ワザ」 小田圭二 他 著
一番最初に出た本です。結構とがった内容を扱っています。
・パフォーマンス分析の考え方(私の担当)
・性能テストや障害テストの仕方、設計の注意点(主に私が執筆)
・コストベースオプティマイザ(10gベース)のアーキテクチャ
・コネクションプーリング
最新のOracleの内容は含んでいませんが、今でも性能の考え方やオプティマイザの考え方は使えるはずです。オプティマイザをここまで解説している本を私は知りません。

●「続・門外不出のOracle現場ワザ」 小田圭二 他 著
「続」の名前の通り、次に出た本です。ちょっと尖り過ぎたかもしれません^^; でも本当に使う内容を選んだつもりです。一流になりたい・他の人と差をつけたい人にお勧めでしょうか。
・性能の良いSQLの書き方
・文字化けの仕組み
・障害(特に性能やハング)の分析・対応方法(私が執筆)
・障害をリアルタイムに分析・対処する方法(私が執筆)
・オプティマイザの使い方ノウハウ
・アップグレードのノウハウ

●「データベース」小田圭二 他 著
私にしては堅い本です。なんせ、共同執筆者が大御所の國友義久先生です。階層型DBMS、ネットワーク型DBMS、リレーショナル型DBMS、XMLDBMS、OO(オブジェクト指向)DBMS、DBMSの持つ機能、DBMSのセキュリティ、データベースの著作権、監査、モデリング、正規化といった内容を網羅しており、深い記述は無いものの、DB技術全体を抑えるのに向いている一冊です。ある程度技術力がついたエンジニアの方が、DB全体を振り返りたい(勉強したい)というときの最初の1冊としてお勧めです。