TOPサーバ構築・運用> 更新できるビューの条件
徹底比較!! PostgreSQL vs MySQLパート2
徹底比較!! PostgreSQL vs MySQLパート2

第8回:それぞれが持つビュー機能
著者:NTTデータ   藤塚 勤也   2007/9/27
前のページ  1  2  3
更新できるビューの条件

   MySQLのビューはそのままで更新可能なことを説明しましたが、更新可能なためには条件があります。それは、作成したビューのレコードとその基になるテーブルのレコードが1対1に対応していることです。

   では、具体的な例で確認してみましょう。

   先ほど作成したTESTV01ビューとは異なる「TESTV02ビュー」を作ってみます。TESTV02ビューはSAMPLEテーブルをCOL01の値でCOL02の値を集計したものです。CREATE VIEW文は以下の通りです(リスト6)。なお、SAMPLEテーブルの値は前述の表1に示す初期状態とします。
リスト6:TESTV02ビューの作成
mysql> create view testv02
as select col01,sum(col02) as col02 from sample
where col01=’A’ group by col01;
mysql> select * from testv02;
+-------+-------+
| col01 | col02 |
+-------+-------+
| A     | 300   |
+-------+-------+

   では、このビューは更新できるでしょうか。UPDATE文の実行結果は以下の通りです(リスト7)。

リスト7:TESTV02ビューの実行結果
mysql> update testv02 set col02 = 10 ;
ERROR 1288 (HY000):
The target table testv02 of the UPDATE is not updatable

   仮にTESTV02ビューが実テーブルであるならば、このUPDATE文の実行結果は「(COL01、COL02)=(’A’、300)」というレコードが「(’A’、10)」に更新されることが期待されます。

   しかしTESTV02はビューであるため「(’A’、300)」というレコードの実体は、SAMPLEテーブルの「(’A’、100)」と「(’A’、200)」の2つのレコードを集計したものです。よって、実体となるSAMPLEテーブルのレコードを更新することができません。

   更新できないというより「どのように更新したらよいのかわからない」といった方が良いかもしれません。このケースでは、TESTV02ビューのレコードとSAMPLEテーブルのレコードとが1対1には対応していないため、結果としてTESTV02ビューの更新ができないという例となります。


PostgreSQLのビューだとどうなるのか

   上記のように、MySQLでは基になるテーブルのレコードと1対1に対応していないビューは更新できないことを具体的に示しました。

   それでは、PostgreSQLのビューの場合はどうなのでしょうか。PostgreSQLのビューはルールの設定がなければ更新できませんが、逆にルールを設定すれば、どのようなビューでも更新できてしまいます。

   例えば、前述したTESTV01ビューの更新用に使用したルール「update_rule」を名称のみ「update_rule2」に変更し、同一内容のものをTESTV02ビューに適用してみます(リスト8)。

リスト8:PostgresSQLのビューの場合
psql> create view testv02
as select col01,sum(col02) as col02 from sample
where col01=’A’ group by col01;
psql> select * from testv02;
 col01 | col02
-------+-------
 A     |   300
psql> create rule update_rule2 as on update to testv02
do instead update sample set col01 = new.col01 , col02 = new.col02
where col01 = old.col01;
psql> update testv02 set col02 = 10;
psql> select * from testv02;
 col01 | col02
-------+-------
A     |    20
psql> select * from sample;
 col01 | col02
-------+-------
 B     |    10
 C     |    10
 B     |    10
 A     |    10
 A

   上記の通り、TESTV02ビューへのUPDATE文は実行可能になります。しかし、その結果は期待するものではありません。要するに「更新処理が実行できること」と「更新処理が期待する結果になること」は、まったくの別物なのです。

   やはりPostgreSQLのビューであっても、MySQLのビューの更新処理制限と同様に「レコードが1対1に対応していないビューは更新不可とする」ためにルールの提供を行わないことこそが、正しい設計だと考えます。

前のページ  1  2  3


NTTデータ  藤塚 勤也
著者プロフィール
株式会社NTTデータ   藤塚 勤也
基盤システム事業本部 オープンソース開発センタ シニアスペシャリスト。
日本タンデムコンピューターズ(現日本HP)を経て、2003年よりNTTデータにてOSS分野に参画。日頃はオリジナルOSSの開発や、OSSを用いたシステム構築への技術支援に従事。「RDBMS解剖学」(翔泳社)を共著。

INDEX
第8回:それぞれが持つビュー機能
  ビューとはなにか
  PostgreSQLのビューの更新
更新できるビューの条件