SQLite | ゼロからはじめるSQL、30日で習得するSQLite:データ操作・設計 - Day23 ビュー

SQL SQLite
スポンサーリンク

Day23 後半

「VIEW は“テーブルの代わり”じゃなく、“SELECT を整理する道具”だと理解する」

前半で、VIEW が
「よく使う SELECT に名前をつけた仮想テーブル」
というところまでは掴めました。

後半ではもう一歩踏み込んで、

ビューを重ねて使うとどうなるか
パフォーマンスと“いつ実行されるか”の話
ビューとテーブルの役割の違い
どんなときにビューを作るべきか
セキュリティ設計としての“ビューの使いどころ”

を、実務寄りの感覚で固めていきます。


ビューの中でビューを使う

「複雑な処理を“段階”に分けて名前をつける」

前半で作った user_totals を思い出してください。

CREATE VIEW user_totals AS
SELECT
  u.id,
  u.name,
  SUM(o.amount) AS total_amount
FROM users u
LEFT JOIN orders o
  ON u.id = o.user_id
GROUP BY u.id, u.name;
SQL

ここからさらに、
「合計金額が 10,000 以上の“優良顧客”だけ」を
よく使うとします。

そのたびに

SELECT * FROM user_totals WHERE total_amount >= 10000;
SQL

と書いてもいいのですが、
これもビューにしてしまえます。

CREATE VIEW vip_users AS
SELECT
  id,
  name,
  total_amount
FROM user_totals
WHERE total_amount >= 10000;
SQL

こうすると、
アプリ側は単に

SELECT * FROM vip_users;
SQL

と書くだけで済みます。

ここで大事なのは、

ビューの中で、別のビューを参照している
=処理を“段階”に分けて名前をつけている

という構造です。

「生のテーブル → 中間ビュー → さらに絞ったビュー」
という階層を作ることで、
SQL 全体の見通しがかなり良くなります。


ビューは“結果を保存している”わけではない

「呼び出されるたびに中の SELECT が展開される」

ここで一つ、誤解しがちなポイントをはっきりさせます。

ビューは、
「SELECT の結果をどこかに保存しておく仕組み」
ではありません。

SQLite のビューは、

呼び出されるたびに
中に書かれた SELECT が“その場で展開されて実行される”

という動きをします。

つまり、

SELECT * FROM vip_users;
を実行するとき、内部的には

vip_users の定義(=SELECT ... FROM user_totals ...)が展開され
さらに user_totals の定義(=JOIN+GROUP BY)が展開され
最終的な 1 本の SELECT として実行される

というイメージです。

この性質から分かる重要なことは二つあります。

ビューを増やしても、データが二重に保存されるわけではない
ビューを重ねすぎると、最終的なクエリが複雑になりパフォーマンスに影響することがある

ビューは「保存」ではなく「定義の再利用」だ、という感覚を持っておくと、
変な期待をせずに済みます。


ビューとテーブルの役割の違い

「テーブルは“データの箱”、ビューは“見せ方の定義”」

ここで一度、テーブルとビューの役割を整理します。

テーブル
データそのものを保存する場所
INSERT / UPDATE / DELETE の対象
インデックスを貼って検索を速くする対象

ビュー
SELECT の定義に名前をつけたもの
基本的には読み取り専用(SQLite ではそう考えておく)
「どの列を見せるか」「どう集計するか」という“見せ方”のルール

つまり、

テーブルは「データの箱」
ビューは「その箱の中身をどう見せるかのレンズ」

という関係です。

このイメージを持っておくと、

「これは本当にテーブルにすべき情報か?」
「これはビューとして定義しておけば十分か?」

という判断がしやすくなります。


どんなときにビューを作るべきか

「3回以上書いた SELECT は、ビュー候補だと思っていい」

実務的な目安を一つ置いておきます。

同じような SELECT を
アプリや SQL の中で 3 回以上書いたら、
それはビュー候補だと思ってください。

例えば、

ユーザーと注文を JOIN して
合計金額を出す SELECT

を、
ダッシュボード
管理画面
CSV 出力

など、あちこちで書いているなら、
それは user_totals のようなビューにしてしまった方がいいです。

ビューにしておけば、

定義変更があったときに直す場所が 1 か所で済む
SQL を読む人が「これは“ユーザー合計”なんだな」と一瞬で理解できる

というメリットがあります。

逆に、

一度しか使わない
ごく単純な SELECT

まで何でもビューにしてしまうと、
ビューの数が増えすぎて
それはそれで全体像が見えなくなります。

「何度も使う」「意味のある名前が付けられる」
この 2 つが揃った SELECT を、
ビューに昇格させるイメージがちょうどいいです。


セキュリティ設計としてのビュー

「“安全な窓”をいくつか用意しておき、生のテーブルは極力触らせない」

前半でも触れましたが、
ビューはセキュリティ設計と相性がとても良いです。

例えば、次のような方針が考えられます。

生の users テーブルには、
パスワードハッシュ・権限フラグ・内部メモなど
機密度の高い列がたくさんある。

アプリからは、
public_users ビューだけを参照させる。
このビューには、id / name / email など
“見せてよい列だけ”を含める。

管理画面用には、
admin_users_view のような別ビューを用意し、
そこには権限フラグなども含める。

こうして、

「誰がどのビューにアクセスできるか」
というレベルで権限を考えると、

「誰がどのテーブルのどの列にアクセスできるか」
よりも、設計がシンプルになります。

SQLite 単体では細かい権限管理は難しいですが、
考え方としては

アプリ側から直接テーブルを触らせず、
ビュー経由でしかデータに触れないようにする

という設計は、
他の RDBMS でもよく使われるパターンです。


ビューを乱用したときの“イヤな未来”も少しだけ想像しておく

道具は便利な分、乱用すると痛い目も見ます。

ビューを作りすぎると、

どのビューがどのテーブルを参照しているのか分からなくなる
ビュー同士が複雑に依存し合い、変更の影響範囲が読めなくなる
最終的なクエリが巨大になり、パフォーマンスのボトルネックになる

といった問題が出てきます。

なので、

「意味のある中間結果にだけ名前をつける」
「ビューの階層は深くしすぎない(2〜3段くらいまで)」

といった“軽いルール”を自分の中に持っておくと、
ビューとの付き合い方がだいぶ健全になります。


Day23 後半のまとめ

ビューは「SELECT の結果を保存している」のではなく、「SELECT の定義に名前をつけた仮想テーブル」であり、呼び出されるたびに中の SELECT が展開されて実行される。
ビューの中でビューを使うことで、「生テーブル → 中間ビュー → さらに絞ったビュー」という“段階”を作り、複雑な処理を分割して整理できる。
テーブルは「データの箱」、ビューは「その箱の中身をどう見せるかのレンズ」という役割の違いを意識すると、どちらにすべきかの判断がしやすくなる。
同じ SELECT を何度も書いているなら、それはビュー候補であり、ビューにすることでロジックを一元化し、変更に強い設計にできる。
ビューは「見せてよい列・行だけを切り出した安全な窓」として使えるため、生テーブルへの直接アクセスを減らし、セキュリティ設計の土台としても活用できる。

ここまで来たあなたは、
「SQL を書く人」から一歩進んで、
「SQL を“設計する人”」の感覚を手に入れつつあります。
ビューはその設計力を支える、かなり重要なピースです。

タイトルとURLをコピーしました