メニューボタン
IBMi海外記事2020.03.11

ビューに目を向ける

Paul Tuohy 著

著者まえがき: この記事は2009年4月に掲載された記事を元にしたものです。その当時と比べるとDDLおよび組み込みSQLの使われ方は大きく変わっていますが、記事の前提となっている基本的な事項は現在も当てはまるものです。元の記事にあった、SELECT *を使用した組み込みSQLの例は、今ではお勧めの手法ではなくなっているため削除しました(コードの自己文書化、パフォーマンス向上の可能性、およびレコード単位で考える古い習慣からの脱却という観点から)。また、関数ではなくDATES表を使用するために、数値日付列を再フォーマットする例に変更を加えています(より迅速かつ適切な手法にするため)。ビューを定義するウィザードを使用する例を削除しました(このウィザードはなくなったため)。また、ビューを使用する際のパフォーマンスに関して、少し加筆を行いました。

先日、同僚と話をしていた際に、従来のDDS(データ定義言語)ではなく、SQLでDDLを使用してデータベースを定義するケースが増えているという話になりました。そして、その時に出た話題の1つに、DDLを使用して表およびインデックスを定義している一方で、ビューが定義されることが極めて少ないように思えるというものがありました。

この記事では、アプリケーション内でビューを使用することによって、そしてユーザーがすぐにデータへアクセスしやすくするための手段としてビューを使用することによって得られるいくつかのメリットについて説明します。

ビューとはどのようなものか

このシステムでより伝統的なやり方を踏襲してきた私たちは、ビューというのはキー付きでない論理ファイルであると考えがちです。これは間違いではないのですが、従来の論理ファイルに比べて、ビューが提供する機能ははるかに多いため、多少、誤解を招く恐れもあります。

ビューに対するもうひとつの見方として、ビューを、永続オブジェクトとして存在するSQLステートメントとみなすというものがあります。ビューをSQLステートメントとみなすことによって、ビューで定義されるものについて、少しイメージが浮かび始めるのではないでしょうか。それでは、従来の論理ファイルと比較して、ビューを定義することで得られるいくつかのメリットについて見てみましょう。

  • より多くの結合のオプションが利用可能です。内部結合、左外部結合、右外部結合、例外結合、およびクロス結合を使用できます。
  • 結合は等しい列に制限されないため、派生列に基づいて結合を指定することもできます。
  • DDSでリモートから可能などのようなものよりもはるかに複雑な派生列を定義できます。通常の式と同様に、SQLスカラー関数に完全にアクセスすることもできます。そのため、列の内容を再キャストまたは再定義するビューを非常に簡単に定義することができます。後ほど例を示します。
  • やはりDDSでリモートから可能などのようなものよりもはるかに有用な選択基準を定義できます。ビュー定義は、SQL where節をフルに活用できます。
  • サマリー情報を含むビューを定義できます。たとえば、地域レベルでの売上のサマリーを提供するビューを定義することもできます。また、サマリー レベルでhaving節を利用することもできます。
  • ビューのビューを定義できます。

ご覧の通り、これらはDDSによって提供される機能をはるかに上回る機能です。上述の点について、ある程度聞き覚えがあるように思われたのだとしたら、それは、上述の点がSQL Selectステートメントについて適切に言い表しているものでもあるからです。そして、ここから、ビューを、永続オブジェクトとして存在するSQLステートメントとみなす見方に戻ります。

認識されている問題

ビューがそれほど万能なのだとしたら、どうしてアプリケーションでもっと使用されていないのでしょうか。その鍵となるのは、ビューがキーを持たないということです。そのため、従来のRPGまたはCOBOLプログラムでビューは使用可能でないと考えがちです。アプリケーションに、キー付きでない論理ファイルはどれくらいあるでしょうか。

しかし、ビューは使用できないというわけではありません。確かに、論理ファイルと同じようにしてビューを使用することはできません。RPG F仕様書でキー付きファイルとしてビューを定義することはできません。ビューにアクセスするには、組み込みSQLを使用する必要があります。ビューによって代わりに行われる作業量を考えると、これはそれほどひどい制約ではでありません。

アプリケーションでビューを使用する

次のコードは、ホスト変数に基づいた選択基準で、4つの表から多数の列を選択するselectステートメントにカーソルを宣言する組み込みSQLステートメントを示しています。

declare C1 scroll cursor For
 select a.session, a.daynum, c.showseq, a.agendaid, a.room,
        b.shorttitle, d.day, d.dayname, c.fromtime, 
        c.totime

 from schedule a inner join sessions b
   on a.session = b.session
   inner join agenda c
   on a.event = c.event and
      a.daynum = c.daynum and
      a.agendaid = c.agendaid
   inner join daynums d
   on a.event = d.event and
      a.daynum = d.daynum
 where a.event = :ForEvent

 order by a.session, a.daynum, c.showseq
 for read only;

ビューを定義することにより、作業をより快適に行えるようにもなります。次のコードをご覧ください。ビューの作成で使用されるselectステートメントは、上のコード例で使用されているものと同じですが、whereおよびorder by節はありません(必要なら、where節を指定することができます)。

create view MyView as (
 select a.session, a.daynum, c.showseq, a.agendaid, a.room,
        b.shorttitle, d.day, d.dayname, c.fromtime, 
        c.totime

 from schedule a inner join sessions b
   on a.session = b.session
   inner join agenda c
   on a.event = c.event and
      a.daynum = c.daynum and
      a.agendaid = c.agendaid
   inner join daynums d
   on a.event = d.event and
      a.daynum = d.daynum);

ビューを定義したことで、組み込みSQLステートメントは次のようにシンプルになりました。

declare C1 scroll cursor For
 select session, daynum, showseq, agendaid, room,
        shorttitle, day, dayname, fromtime, 
        totime

 from MyView
 where a.event = :ForEvent

 order by session, daynum, showseq
 for read only;

SQLステートメントに問題があった場合(考えたくもないことですが)に、RPGプログラムではなく、ビューで問題をデバッグできるというメリットも生まれます。

データにアクセスしやすくする

ビューを使用することにより、システムで定義した任意のデータは、ユーザーにとってさらに読みやすいものになります。たとえば、従業員のID、名前、生年月日が含まれるDDS定義の物理ファイルがあるとします。生年月日は、数値フィールドとして定義されています。少しでもデータにアクセスしやすくするために、DATES表を利用することができます。この表には、1日につき1つの行、および必要となり得るすべての日付の順列と組み合わせを表現する列が格納されています。次のビューには、数値データ フィールドに代わって、適切な日付を取得するために使用されるDATES表が示されています。

CREATE VIEW EMPVIEWA ( EMPNO , NAME , BIRTHDATE )
AS SELECT EMPNO, NAME, ISODATE  
FROM EMPLOYEES INNER JOIN DATES ON BIRTHDATE = YYYYMMDD;

さらに先へと進みましょう。これで基本的なビューができたので、そのビューのもうひとつのビューを定義します。これは従業員の年齢を示します。たとえば、

CREATE VIEW EMPVIEWB ( EMPID , NAME , BIRTHDATE , AGE )
  AS SELECT EMPNO, NAME, BIRTHDATE, 
            YEAR( CURDATE( ) - BIRTHDATE)
     FROM EMPVIEWA ;

この例から、どのようにビューを使用したらDDS定義のファイルさえも再定義および拡張できるかということが分かると思います。また、これはビューのビューを定義するシンプルな例でもあります。

終わりに

パフォーマンスについて少し述べておきたいと思います。ビューはキー付きでない(すなわち、ビューはアクセス パスが関連付けられていない)ため、メンテナンスのオーバーヘッドを生じません。パフォーマンスのオーバーヘッドは、ビューが使用されたときにのみ生じます。つまり、どのインデックスが最も適切に要求されたデータを提供するかをQuery Engineが判定する時点です。

ビューのビューのビューがある場合でも、余分なパフォーマンスのオーバーヘッドはありません。Query Engineは、ステートメントと、ビューの各selectステートメントから1つのSQL selectステートメントを構築します。これは、ビューがなかったとしたら使用する必要があったステートメントです。

さて、まだビューを使用したことがないのだとしたら、どうぞ試してみてください。ビューを無視したままでいると、多くの機会を失うことになります。

大いに楽しんでください。

あわせて読みたい記事

PAGE TOP