ビュー(InterBaseおよびFirebird)
Alexey Kovyazin、最終更新日:2012年4月13日
SQL言語に精通している方には、このテーマについての詳細な説明は不要ですが、プレゼンテーションの順序を保つために、ビューの簡単な定義を紹介します。
VIEW(ビュー)は、通常のテーブルへの問い合わせに基づいて作成される仮想テーブルです。ビューは、サーバーに保存され、ビューを参照するたびに実行される問い合わせとして実装されます。
ビューのさまざまな使用例を考えてみましょう。ビューにより、データ構造のレベルを作成し、データストレージの実装をそのタイプから分離することができます。たとえば、複数のテーブルからデータを選択するビューを作成できます。クライアントが基になるテーブルを直接参照する代わりにこのビューを使用する場合、データベース開発者はビューの基になるクエリを変更したり、変更(たとえば最適化)したりすることができ、クライアントは何も気付かないでしょう - 彼にとっては同じビューです。ビューは、データストレージの実装をユーザーから分離するという事実に加えて、データをより便利でシンプルな方法で整理することを可能にします。データ構造の「簡素化」の問題は、データベース内のテーブル数が十分に大きくなり、それらの間の相互関係が複雑になったときに発生します。ビューにより、特定のデータベースクライアントに不要な(または必要な)データの一部を排除(または逆に追加)できます。
さらに、ビューにより、InterBaseデータベースのセキュリティをより簡単に整理できます。一部のユーザーは、ビューのデータを読み取り/更新する権限のみを持ち、ビューの基になるテーブルに対する権限(およびその存在についての知識さえも)を持たないようにできます! InterBaseのセキュリティの詳細については、「InterBaseのセキュリティ:ユーザー、その機能と権利」(パート4)の章を参照してください。
ビューを操作するためのDDL構文
次に、DDL(Data Definition Language - SQLサブセット、用語集を参照)で定義されたビューの作成および削除のコマンドを検討します。InterBaseでビューを作成するには、次の構文の文を使用する必要があります:
CREATE VIEW viewname [(view_column[, view_column…])] AS [WITH CHECK OPTION];
ここで、viewnameはデータベース内で一意である必要があるビューの名前であり、その後にビューに含まれるフィールドの名前のグループ(常に必須ではない)が続きます:[(view_column [, view_column …])]。ビューに含まれるデータを選択するステートメントを定義することが不可欠です。オプションのパラメータWITH CHECK OPTIONについては、「変更可能なビュー」のパートで後ほど説明します。
ビューを変更するには、ビューを再作成する必要があります。つまり、削除してから再度作成します。ビューを削除するときは、依存するすべてのオブジェクト(トリガー、ストアドプロシージャ、他のビュー)も削除する必要があります。これはビューを操作する際の主な不便さの1つです:ビューを使用するオブジェクトのツリーを再作成する必要があることです(これを容易にするユーティリティがあります。たとえばIBAlterView。アプリケーション「管理者およびInterBaseデザイナーツール」を参照してください)。ビューを削除する場合は、次のDDLコマンドを使用する必要があります:
DROP VIEW viewname;
ビューの例
簡単なビューの例を示します:
CREATE VIEW MyView AS SELECT NAME, PRICE_1 FROM Table_example;
この例では、「テーブル。主キーとジェネレーター」の章で検討したTable_exampleテーブルへのクエリに基づいてビューを作成します。この場合、ビューはTable_exampleテーブルから条件なしで選択されるNAMEとPRICE_1の2つのフィールドで構成されます。つまり、ビューMyViewのレコード数はTable_exampleのレコード数と等しくなります。ただし、ビューは常にこれほど単純であるとは限りません。複数のテーブルのデータや、他のビューに基づくこともできます。さらに、ビューには、さまざまな式(集計関数を含む)に基づいて取得されたデータを含めることができます。このビューアプリケーションの使用法をより詳細に検討するために、1対多の関係(このような関係はマスター-ディテールと呼ばれることがよくあります)で結合された2つのテーブルを作成しましょう。これらのテーブルを作成するためのDDLスクリプトは次のとおりです:
/\* Table: WISEMEN */
CREATE TABLE WISEMEN ( ID_WISEMAN INTEGER NOT NULL, WISEMAN_NAME VARCHAR(80));
/\* Primary keys definition */
ALTER TABLE WISEMEN ADD CONSTRAINT PK_WISEMEN PRIMARY KEY (ID_WISEMAN);
/\* Table: WISEBOOK */
CREATE TABLE WISEBOOK ( ID_BOOK INTEGER NOT NULL, ID_WISEMAN INTEGER, BOOK VARCHAR(80));
/\* Primary keys definition */
ALTER TABLE WISEBOOK ADD CONSTRAINT PK_WISEBOOK PRIMARY KEY (ID_BOOK);
/\* Foreign keys definition */
ALTER TABLE WISEBOOK ADD CONSTRAINT FK_WISEBOOK FOREIGN KEY (ID_WISEMAN) REFERENCES WISEMEN (ID_WISEMAN);
これで、FOREIGN KEY制約を使用してマスター-ディテール関係で結合されたWISEMENとWISEBOOKの2つのテーブルを作成しました。これらのテーブルには、偉大な中国の賢人とその著作に関する情報が格納されると仮定しましょう。次に、これらのテーブルに基づいていくつかのビューを作成できます。たとえば、各賢人が何冊の著作を持っているかを示すビューを作成しましょう:
CREATE VIEW WiseBookCount (WISEMAN, HOW_WISEBOOKS) AS SELECT M.WISEMAN_NAME, COUNT(B.BOOK) FROM WISEMEN M, WISEBOOK B WHERE (M.ID_WISEMAN = B.ID_WISEMAN) GROUP BY M.WISEMAN_NAME
COUNT()、SUM()、MAX()などの集計関数のような計算式を使用する場合は、ビューのフィールド名を明確に定義すること、つまりクエリによって返されるすべてのフィールドに名前を付けることが不可欠であることに注意してください。この例からわかるように、これらの名前はクエリのフィールド名と必ずしも一致する必要はありませんが、その数はクエリによって返されるフィールドの数と一致する必要があります。問い合わせによって返されるフィールドがビューのどのフィールドに対応するかの定義は、シリアル番号によって行われます - 最初のクエリフィールドはビューの最初のフィールドに反映され、2番目は2番目に反映される、などです。
そして、どの賢人が最も多くの本を書いたかを知りたい場合はどうでしょうか? ビューの基になるクエリにソートの式 - ORDER BYを追加してみます。ただし、この試みは成功しません:ビューでのORDER BYソートの使用は許可されておらず、ORDER BYを含むクエリでビューを作成しようとすると、エラーが発生します。ビューによって返された結果をソートしたい場合は、クライアント側で行う必要があります:
SELECT * FROM WiseBookCount ORDER BY HOW_WISEBOOKS
このSQLクエリの実行により、望ましい結果が得られます。ビューでのORDER BY式の使用に関する制約に加えて、ストアドプロシージャの実行結果として取得されたデータセットをデータソースとして使用することもできません(以下の「ストアドプロシージャ」の章を参照してください)。
おそらく、ビューのアプリケーションを示すもう1つの例を示す価値があります。名前が文字「K」で始まる賢人のリストを出力する必要があると仮定しましょう。この場合、条件付きのビューを使用します:
CREATE VIEW WiseMen2 (WISEMAN) AS SELECT M.WISEMAN_NAME FROM WISEMEN M WHERE M.WISEMAN_NAME LIKE ‘K%’
このように、特定の条件に従ってデータベースからデータを選択し、常に更新可能なデータサプライヤーの役割を果たすビューを簡単に作成できます。
変更可能なビュー
上記で、変更可能なデータビューを作成する機能があることに言及しました。実際にその通りです - ビューからデータを読み取るだけでなく、変更することもできます!
ビューを変更可能にするには2つの方法があります。最初の方法は、ビューが単一のテーブル(または他の変更可能なビュー)に基づいて作成され、そのテーブルのすべての列がNULLの存在を許可する必要がある場合に適用されます。したがって、ビューの基になるクエリには、サブクエリ、集計関数、UDF、ストアドプロシージャ、DISTINCTおよびHAVINGステートメントを含めることはできません。これらの条件がすべて満たされている場合、ビューは自動的に変更可能になります。つまり、DELETE、INSERT、UPDATEクエリを実行でき、ソーステーブルのデータが変更されます。
条件のリストはかなり印象的で、このような変更可能なビューのアプリケーションを大幅に制限するため、これらが使用されることはかなりまれです。
为了创建违反上述任何条件的修改视图,需要应用触发器机制。有关触发器的更多详细信息,请参阅“触发器”章节(第1部分)。现在,我们仅考虑在VIEW中组织数据修改的一般原则。
为了使用触发器实现可更新的视图,必须完成以下操作。为给定视图创建3个触发器,分别针对事件:BEFORE DELETE、BEFORE UPDATE和BEFORE INSERT。在这些触发器中描述删除、更新和插入时应如何处理数据。
然后,我们应该在修改查询中使用给定的视图–DELETE、INSERT或UPDATE。当InterBase收到此查询时,它将检查给定视图是否存在相应的触发器,即BEFORE DELETE/INSERT/UPDATE。如果存在针对可执行操作的触发器,InterBase将调用它来修改视图底层表中的真实数据(尽管也可以是其他数据–这些触发器没有文本约束),然后重新读取被修改的字符串(或字符串组)。
因此,可以实现视图中复杂的数据更新链。
在创建视图的语法描述中提到了WITH CHECK OPTION选项。如果在创建修改视图时设置了此选项,则插入或更改到此视图中的每个数据字符串都将根据进入视图的条件进行检查。可以这样解释:如果用户插入的新记录或作为更新现有记录的结果而获得的记录不满足作为VIEW数据源的查询条件,则此记录的插入将被取消,并产生错误。
结论
尽管创建和使用视图看似简单,但它们为改善数据库中的数据组织提供了强大的能力,并允许创建数据组织的层次结构。
一些数据库应用程序设计者经常在工作中使用视图,而另一些则避免使用它们,理由是视图的修改复杂,并倾向于尽可能保持数据库方案的简单和高效。如何在工作中应用视图取决于您自己。最重要的是记住视图这样强大工具的存在,并知道如何使用它。