更新可能ビューとINSTEAD OFトリガー
ビューを直接更新可能にする方法や、ビューでデータを集約・結合する場合にINSTEAD OFトリガーを使う方法を学びます。
「更新可能ビューと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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 通常のビュー:論理的な再利用
- 更新可能ビューとINSTEAD OFトリガー
- マテリアライズドビューとREFRESH戦略
- 事前集計を行うタイミング