DBMSのビュー機能って言うのは、簡単にいえばSELECT文でテーブルの複製のようなものを構築する機能。
例えば、
orderテーブル
id
item_id
unit
itemテーブル
id
name
price
みたいなテーブルがあって、ビューを
CREATE VIEW order_view AS SELECT order.id, name, unit*price as total_price FROM order, item WHERE order.item_id = item.id
の様に定義しておくと、id, name, total_priceを持つビューができる。
ビューはテーブル同様、 SELECT * FROM order_view の様に処理できる。
CREATE TABLE ~ SELECT ~形式でテーブルを作ると似た結果になるが、CREATE TABLE ~ SELECT ~では、CREATE TABLEしたタイミングの情報がテーブルに保持されるのに対して、ビューはビューに対してクエリが投げられる度に、AS~の文を実行してデータを取得する。
よく使う取得形式について、SELECT *で済ませる様に定義したり、制限ユーザにテーブル全項目ではなくカラムを限定してビューとして提供したり、内部構造の変更を吸収するレイヤーとして使うことができる。
便利に思えるビューではあるが、色々と制限もある。
例えば更新系クエリ(INSERTやUPDATE)は、レコードが一意に元テーブルのレコード・カラムを特定できる事が最低条件である。
先に示した定義の場合、total_priceはunitとpriceの演算により求められるカラムであり、total_priceが元テーブルにどのような値を与えるか不定であるから更新できない。
手の込んだ構造のビューは基本的に更新できない、見る(view)ためだけの物であると考えたほうが良い。
また、ビューにはインデックスを設定することもできない(クエリを投げた段階でSELECTしてデータを取得するので、SELECT後にインデックスを構築して検索したとしても、コストが増えるだけ)ため、パフォーマンス的に弱いし、集計操作などにも癖がある。
パフォーマンス制限について、一回の接続で繰り返し同じビューを利用するなら、ビューではなく、一時テーブル(CREATE TEMPORARY TABLE ~)を接続するたびに構築した方が高速な事もある(接続中はマスタの変更は反映されないし、更新系は結局、元テーブルに投げなければならないが)
1 |
CREATE TABLE new_tbl SELECT * FROM orig_tbl;C |
(93)