3秒でわかる
SELECT 文に名前をつけて表のように扱える仕組み。長い結合や条件を隠して、利用側が短い SQL で読めるようにするために使います。
もう少し詳しく
どういうものか
ビューは、SELECT 文に名前をつけて登録し、以後その名前をテーブルのように参照できる仕組みです。実体としてデータを持たないため仮想表と呼ばれます。ビューを参照すると、データベースは登録された SELECT 文をその場で実行して結果を返します。元のテーブルが更新されれば、ビューの内容も自動的に最新になります。
なぜ必要か
3 つのテーブルを結合し、退会済みを除外し、金額を集計する。この処理を画面ごとに書き直していると、除外条件を 1 つ足すだけで全箇所の修正が必要になります。ビューにまとめておけば定義は 1 か所です。
権限の分離にも使えます。給与テーブルそのものへの参照権は与えず、氏名と部署だけを並べたビューにだけ権限を与えれば、閲覧できる列を絞れます。
具体例
注文と顧客を結合した集計をビューにします。
CREATE VIEW active_customer_sales AS
SELECT
c.id AS customer_id,
c.name AS customer_name,
COUNT(o.id) AS order_count,
SUM(o.amount) AS total_amount
FROM customers AS c
<a href="/glossary/join" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">JOIN</a> orders AS o ON o.customer_id = c.id
WHERE c.withdrawn_at IS NULL
GROUP BY c.id, c.name;
SELECT customer_name, total_amount
FROM active_customer_sales
WHERE total_amount >= 10000
ORDER BY total_amount DESC;利用側は結合も除外条件も知らずに済みます。定義を変えたいときは CREATE OR REPLACE VIEW で差し替えます。
つまずきやすいところ
「ビューにすれば速くなる」という誤解が一番多い落とし穴です。ビューは問い合わせの保存であって結果の保存ではないため、参照するたびに中の SELECT が実行されます。速度が欲しい場合は、結果を実際に保持するマテリアライズドビューか、集計済みのテーブルを別に用意します。
もう 1 つは更新の可否です。単一テーブルで集計も DISTINCT も含まない単純なビューなら INSERT や UPDATE が通ることがありますが、GROUP BY や JOIN を含むビューは更新できません。
似た用語との違い
| 用語 | データの実体 | 最新性 |
|---|---|---|
| ビュー | 持たない | 常に最新 |
| マテリアライズドビュー | 持つ | 更新時点のもの |
| 一時表 | 持つ | セッション内だけ |
覚え方
ビューは保存された SELECT 文であって、保存されたデータではありません。ここを取り違えなければ大半の疑問は解けます。