ITの教科書検索
入門読了 約9分

データベースのビューとは ― 仮想テーブルの仕組み

データベースのビューは、SELECT文の定義を保存した仮想的なテーブルで、長い問合せの短縮や見せる列の制限に使います。更新できるビューの条件を図で確かめられます。

目次
  1. ビューとは
  2. CREATE VIEWの書き方
  3. テーブルとの違い
  4. ビューを使う目的
  5. 更新できるビューの条件
  6. 練習問題

ビューとは、SELECT文の定義を保存した仮想的なテーブル

データベースのビューとは、SELECT文の定義を保存した仮想的なテーブルです。長い結合を毎回書く代わりに短い名前で呼び出したり、利用者に見せる列を絞ったりするのに使います。テーブルと同じようにSELECT文のFROM句に書いて参照できますが、行のデータ自体は保存しません。

ビューの定義には、SQLの基本のSELECT文をそのまま使います。CREATE VIEWの後にSELECT文を書くと、そのSELECT文がビューの中に保存されます。

ビューを参照するたびに、保存したSELECT文が実行され、実テーブル(データを実際に保存しているテーブル)のその時点の値が返ります。利用者ごとに見せる形を決めるビューは、3層スキーマでは外部スキーマに当たります。

CREATE VIEWの後にSELECT文を書くと、参照のたびに実テーブルへ置き換わる

ビューを作るには、CREATE VIEWの後にビュー名を書き、ASの後に通常のSELECT文を書きます。

CREATE VIEW 開発部員 AS
SELECT 社員ID, 氏名, 給与
FROM 社員
WHERE 部署ID = 1;

この文を実行すると、社員テーブルから部署IDが1の行を選ぶSELECT文が、開発部員という名前で保存されます。社員テーブルの行は複製されず、SELECT文だけが保存されます。この定義は、関係演算でいう選択で行を絞り、射影で3つの列を取り出す形です。

SELECT * FROM 開発部員; のようにビューへ問い合わせると、データベースは保存したSELECT文に置き換えて実行します。実際に検索するのは社員テーブルなので、その時点の給与の値が結果に反映されます。

CREATE VIEWSELECT文を保存ビューへのSELECT利用者が実行する文保存した文に置き換え実テーブルを対象に結果その時点の値あとでDBが変換検索作成時に1回だけ問い合わせのたびにCREATE VIEWSELECT文を保存ビューへのSELECT利用者が実行する文保存した文に置き換え実テーブルを対象に結果その時点の値あとでDBが変換検索1回だけ毎回
CREATE VIEWはSELECT文を保存するだけで、データ自体は保存しません。ビューへのSELECTは、保存したSELECT文に置き換えられて実テーブルを検索し、その時点の値を返します。

テーブルとビューの違いは、データそのものを保存するかどうか

テーブルは行のデータを保存しますが、ビューはSELECT文の定義だけを保存します。データを保存するテーブルは、列と制約を定義して作ります。作り方はCREATE TABLEと制約の記事で説明しています。

テーブルとビューの違い
項目テーブルビュー
データの保存行のデータそのものを保存するSELECT文の定義だけを保存し、行のデータは保存しない
参照したときの動き保存されている行をそのまま返す保存したSELECT文を実行し直し、実テーブルのその時点の値を返す
ディスクの使用量行数に応じて増える定義だけなので、ほとんど増えない
INSERT・UPDATE・DELETE常にできる条件を満たすときだけできる

結果のデータまで保存する仕組みをマテリアライズドビュー(実体化ビュー)と呼びます。通常のビューとは別のものです。

ビューを使う目的は、SQL文を短くすることと見せる範囲を絞ること

結合や絞り込みを含む長いSELECT文も、一度ビューにしておけば短い名前で呼び出せます。JOINの記事で説明した結合も、問い合わせのたびに書かずに済みます。

もう1つの目的は、利用者に見せる列や行を絞ることです。たとえば社員テーブルから給与の列を除いたビューを作り、利用者にはそのビューを参照する権限だけを与えます。すると利用者は、社員テーブルの給与の列を見られません。権限の与え方は、GRANT文・REVOKE文の記事で説明しています。

更新できるビューの条件は、ビューの1行が実表の1行に対応すること

ビューは、条件を満たせばテーブルと同じようにINSERT・UPDATE・DELETE文で更新できます。ビューへの更新は、元になった実表の行に書き込まれます。基本になる条件は、ビューの1行が実表の1行に対応していることです。

集約関数・GROUP BY・HAVING・DISTINCTを使ったビューは、この対応がないため更新できません。PostgreSQLとMySQLの公式ドキュメントは、どちらもこれらを更新できない条件に挙げています。

結合したビューの扱いは製品によって違います。PostgreSQLは、FROM句に表が1つだけのビューしか自動的には更新しません。MySQLは内部結合のビューでも、1つの表の列だけを変えるUPDATEなら受け付けます。SQLiteのビューは、そのままでは更新できません。次の図で、どんなビューなら更新できるかを確かめられます。

ビューを作るCREATE VIEW文

CREATE VIEW 開発部員 AS
SELECT 社員ID, 氏名, 給与
FROM 社員
WHERE 部署ID = 1;

このビューに対するUPDATE文

UPDATE 開発部員
SET 給与 = 給与 + 10000
WHERE 社員ID = 101;

このUPDATE文の結果

  • PostgreSQL○更新できる
  • MySQL○更新できる
  • SQLite×更新できない

FROM句が社員テーブル1つだけで、集約関数もGROUP BYも使っていません。ビューの1行は社員テーブルの1行とそのまま対応するため、PostgreSQLやMySQLでは、UPDATEは社員テーブルの該当行を書き換えます。SQLiteのビューは読み取り専用なので、この形でも更新できません。

集約関数とGROUP BYを使ったビューが更新できないのは、1つの集計結果が元になった複数行のどれに対応するかが決まらないためです。結合したビューでは、部署テーブルの1行がビューの複数の行に現れます。MySQLでこのビューの部署名を書き換えると、同じ部署の全員の行で部署名が変わります。

参考にした資料

練習問題(全5問)

Q1データベースのビューの説明として最も適切なものはどれ?
Q2CREATE VIEW 社員一覧 AS SELECT 氏名, 給与 FROM 社員; を実行したとき、保存されるものはどれ?
Q3更新できるビューの条件として正しいものはどれ?
Q4部署IDごとにSUM(給与)を求めるビューで、合計給与を書き換えるUPDATE文が実行できないのはなぜ?
Q5マテリアライズドビュー(実体化ビュー)が、通常のビューと違う点はどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

データベースの記事を続けて読む

データベース 全36本中21本目