最終更新: yutoritaro 2012年02月21日(火) 16:03:10履歴
クエリー(SELECT文)の結果は常に表(のイメージ)である、ということ。これは複数行を返す場合だけでなく、
たとえば、サブクエリの結果も「表」なので、表と表とのJOIN同様のselect文を書くことができる。
≪サンプルクエリー: サブクエリーにMEM_JPNという名前をつけPREF_MSTとJOINしている≫
select
*
from
(select * from MEMBER_MST where COUNTRY_CD = 'JPN') MEM_JPN
left join PREF_MST on (MEM_JPN.PREF_CD = PREF_MST.PREF_CD)
;
- 1行だけが返るクエリーでは、1行だけある表が返って来ている
- 1つの値だけが返るクエリーでは、1列×1行の表が返って来ている
たとえば、サブクエリの結果も「表」なので、表と表とのJOIN同様のselect文を書くことができる。
≪サンプルクエリー: サブクエリーにMEM_JPNという名前をつけPREF_MSTとJOINしている≫
select
*
from
(select * from MEMBER_MST where COUNTRY_CD = 'JPN') MEM_JPN
left join PREF_MST on (MEM_JPN.PREF_CD = PREF_MST.PREF_CD)
;
Oracleのドキュメントによれば、
ビューは論理表で、1つ以上の表またはビューがベースとなります。ビューにデータそのものが格納されているわけではありません。ビューの基礎になる表を実表といいます。
→ 要するに、クエリーに別名(=viewの名前)をつけて、ストックしておくようなもの。
≪ビュー定義の例: 会員マスターから東京のレコードだけを選び出したビュー≫
create view MEM_TOKYO as select * from MEMBER_MST where PREF_CD = '13'
より視覚的なサンプル>Synergyの「ビュー機能」
尚、このような否定的な意見もありますが、筆者的には「スーパーソルジャー病」のほのかに感じています。DBに関わる何かを毛嫌いするアプリケーションエンジニアをしばしば見かけますが、要はシステムの設計思想との兼ね合いだし、何事も濫用はいくないというだけ、というのが筆者見解です。
ビューは論理表で、1つ以上の表またはビューがベースとなります。ビューにデータそのものが格納されているわけではありません。ビューの基礎になる表を実表といいます。
→ 要するに、クエリーに別名(=viewの名前)をつけて、ストックしておくようなもの。
≪ビュー定義の例: 会員マスターから東京のレコードだけを選び出したビュー≫
create view MEM_TOKYO as select * from MEMBER_MST where PREF_CD = '13'
より視覚的なサンプル>Synergyの「ビュー機能」
尚、このような否定的な意見もありますが、筆者的には「スーパーソルジャー病」のほのかに感じています。DBに関わる何かを毛嫌いするアプリケーションエンジニアをしばしば見かけますが、要はシステムの設計思想との兼ね合いだし、何事も濫用はいくないというだけ、というのが筆者見解です。
- サブクエリーの再利用性の向上
- 名称の取得等、参照するときに必ず行うJOINを予め定義しておくことで、アプリケーションで書くクエリーがシンプルになる
- ありがちな失敗、「画面や帳票の表示項目通りのテーブル設計」をしない代わりに、それをビューにより実現できる
- アクセス制御
- 実表への直接の参照権限を制限し、代わりに、業務で利用していない列等不必要なデータを省いたビューを作り、そこへの参照権限を与える等
- 「ビューは遅い」
- ○ビューは所詮はクエリーなので、重たいクエリーは当然遅いです
- △ビューに対するクエリー、ビュー定義のクエリー共があまり複雑でなく、元表に適切なindexが設定されていれば普通に早いかも
- ★対策もある(→マテリアライズドビュー)
- 更新が面倒くさい。
- ▲シンプルなビューであればそのまま、実はinsertやupdateできる
- ○とはいえ、joinやunionをしているとできないことも多いし、ビューでは隠している元表の列にはdefault値しか入れられない
- ★対策もある(→instead of トリガー)
- 元表が変更されたときに人知れず定義エラーとなることがある
- ○仕様です、というか表定義を変えればエラーになるクエリーもありますよね
- 概要
ビューとはいいつつも、その定義となるクエリーの結果を実体として(マテリアライズドして)予め用意しておくという発想。
重たい集計ビューを早くしようとしてOracleがひねりだしたソリューション、DB2でも採用されている。
定期的にバッチ処理で更新する一時テーブルのようなものをDBMSの機能として提供してくれる。
※以下筆者の甲斐性によりOracleの話がベースです、というか、他はあんまりしらn(ry
- 利点
- 物理的な実体があるので新たに index を定義できる(→高速アクセス可能)
- とはいえビューなので元表の更新に応じて自動で反映される(→一時テーブル方式と違って定期バッチを開発する必要がない)
- 「クエリーリライト」とかまでやってくれる(Oracle Enterprize Edition限定)
- クエリーリライトとは、元表への参照のあるクエリーを普通に書いただけで、実はマテリアライズドビューを使った方が早いと(OracleのOptimizerが)判断した場合、マテリアライズドビューへの参照と内部的に書き替え(=リライトする)て実行する。
- →結果的に、マテリアライズドビューを作るだけで、既存アプリケーションには何も手を加えなくてもパフォーマンスが大幅に改善する可能性がある!
- 利点の裏側
- 物理的な実体がある、つまり、それだけディスク容量を消費する
- 自動更新自体がDBへの負荷となるので、実際には元表への更新をどのタイミングで反映させるかは設定する必要がある(リフレッシュの設定参照)
- リフレッシュ設計を失敗すると、データの整合性の担保が不安定になるリスク有
- リフレッシュの設定
- タイミングに関するもの
- 手動リフレッシュ(なんとデフォルト): リフレッシュコマンドが実行される都度
- 定時リフレッシュ: 一定時間毎に実行、この設定だとバッチによる一時表に近いイメージで動作する
- on commitリフレッシュ: 元表への更新がcommitされる都度
- on demandリフレッシュ: マテリアライズドビューへの
- 内容に関するもの
- 完全リフレッシュ: 元表の全データについてもう一度計算し直す(=定義クエリーが重たいものであれば、その分大きな負荷となる)
- 高速リフレッシュ: 元表への更新に応じて差分をリフレッシュする、その為低い負荷で済む。しかし、ビュー定義のクエリーが複雑な場合には、指定できない場合もある。また、元表への更新を監視する為に「マテリアライズドビューログ」を作っておく必要がある
- タイミングに関するもの
このページへのコメント
ZrYfnD Really appreciate you sharing this article post.Much thanks again. Want more.