SQL Academy · レッスン

更新可能ビューとINSTEAD OFトリガー

ビューを直接更新可能にする方法や、ビューでデータを集約・結合する場合にINSTEAD OFトリガーを使う方法を学びます。

レッスン 2/413 ステップ

「更新可能ビューとINSTEAD OFトリガー」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

自動的に更新可能なビュー

PostgreSQL は単純なビューを自動的に更新可能にします。ビューに対する INSERT/UPDATE/DELETE は、基になるテーブルに対する同じ操作に書き換えられます。

CREATE VIEW active_users AS
  SELECT id, email, full_name FROM users WHERE deleted_at IS NULL;

UPDATE active_users SET full_name = 'Alice' WHERE id = 1;
-- Translates to UPDATE on the users table.

自動更新可能にするための要件

ビューは次の条件を満たす必要があります。

  • 基になるテーブルを 1 つだけ参照する
  • 集計、GROUP BY、HAVING、DISTINCT がない
  • LIMIT、OFFSET がない
  • 集合演算(UNION など)がない
  • 列を直接マッピングする(SELECT リストに式がない、または一部の列だけに式がある)

WITH CHECK OPTION

ビューから見えなくなる行を作成する書き込みを禁止します。

CREATE VIEW active_users AS
  SELECT * FROM users WHERE deleted_at IS NULL
  WITH CHECK OPTION;

INSERT INTO active_users (email, deleted_at) VALUES (..., NOW());
-- ERROR — would create a row outside the view's WHERE.

複雑なビューには INSTEAD OF が必要

JOIN、集計、式を含むビューは自動的には更新できません。書き込みの意味を定義する INSTEAD OF トリガーを作成する必要があります。

CREATE VIEW user_with_address AS
  SELECT u.id, u.email, a.city, a.country
  FROM users u JOIN addresses a ON a.user_id = u.id;

CREATE TRIGGER user_addr_update
INSTEAD OF UPDATE ON user_with_address
FOR EACH ROW EXECUTE FUNCTION update_user_addr();

INSTEAD OF トリガー関数

この関数が、どの基になるテーブルに書き込むかを決定します。

CREATE FUNCTION update_user_addr() RETURNS TRIGGER AS $$
BEGIN
  UPDATE users SET email = NEW.email WHERE id = NEW.id;
  UPDATE addresses SET city = NEW.city, country = NEW.country WHERE user_id = NEW.id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

アプリケーションロジックより INSTEAD OF が適する場合

多くの利用者がビューを更新する場合は、更新ロジックをトリガーに集約すると一貫性を保てます。更新するアプリが 1 つだけなら、ロジックはアプリケーションコードに置いてください。

SECURITY BARRIER

プランナーが信頼できないビュー利用者の述語を漏えいさせることを防ぎます(コストを介した情報漏えい)。

CREATE VIEW my_things AS
SELECT * FROM things WHERE owner_id = current_user_id()
WITH (security_barrier);

代替手段としての行レベルセキュリティ

最新の PostgreSQL では、基になるテーブルで行レベルセキュリティ(RLS)もサポートされています。セキュリティビューを構築するより、こちらのほうがすっきりすることがよくあります。

ALTER TABLE things ENABLE ROW LEVEL SECURITY;
CREATE POLICY owner_only ON things USING (owner_id = current_user_id());

再帰ビュー

PostgreSQL は再帰ビューをサポートしています(階層構造を SELECT できます)。

CREATE RECURSIVE VIEW tree (id, parent_id, depth) AS
  SELECT id, parent_id, 0 FROM nodes WHERE parent_id IS NULL
  UNION ALL
  SELECT n.id, n.parent_id, t.depth + 1
  FROM nodes n JOIN tree t ON n.parent_id = t.id;

権限

基になるテーブルではなく、ビューに対して権限を付与します。

GRANT SELECT, UPDATE ON active_users TO app_user;

パフォーマンスに関する注意

INSTEAD OF トリガーは 1 行ごとに実行されます。そのため、大量の DML では遅くなります。多くの場合、呼び出し元が基になるテーブルに直接書き込むほうが適しています。

まとめ

ビューは書き込み可能にできます。

  • 単純なビュー:自動的に更新可能
  • 複雑なビュー:INSTEAD OF トリガーを使用
  • WITH CHECK OPTION:可視性を強制
  • RLS のほうがすっきりしたセキュリティモデルになることが多い

クイックチェック

2 つのテーブルを JOIN するビューを定義しました。デフォルトで、そのビューを通して UPDATE できますか。

無料で開始

AI チューターと学ぶ SQL — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
46
レッスン
183

よくある質問

「更新可能ビューとINSTEAD OFトリガー」レッスンは無料ですか?

はい。「更新可能ビューとINSTEAD OFトリガー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「更新可能ビューとINSTEAD OFトリガー」で何を学びますか?

ビューを直接更新可能にする方法や、ビューでデータを集約・結合する場合にINSTEAD OFトリガーを使う方法を学びます。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「更新可能ビューとINSTEAD OFトリガー」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 通常のビュー:論理的な再利用
  2. 更新可能ビューとINSTEAD OFトリガー
  3. マテリアライズドビューとREFRESH戦略
  4. 事前集計を行うタイミング
← SQL Academyに戻る