MySQL 8.0 リファレンスマニュアル


13.1.23 CREATE VIEW ステートメント

CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = user]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

CREATE VIEW ステートメントは、新しいビューを作成するか、OR REPLACE 句が指定されている場合は既存のビューを置き換えます。 そのビューが存在しない場合、CREATE OR REPLACE VIEWCREATE VIEW と同じです。 ビューが存在する場合は、CREATE OR REPLACE VIEW によって置換されます。

ビューの使用に関する制限の詳細は、セクション25.9「ビューの制約」 を参照してください。

select_statement は、そのビューの定義を提供する SELECT ステートメントです。 (ビューから選択すると、実質的には SELECT ステートメントを使用して選択されます。) select_statement では、実テーブルや他のビューから選択できます。 MySQL 8.0.19 以降、SELECT ステートメントは VALUES ステートメントをソースとして使用することも、CREATE TABLE ... SELECT と同様に TABLE ステートメントに置き換えることもできます。

ビュー定義は作成時の「冷凍」であり、基礎となるテーブルの定義に対する後続の変更の影響を受けません。 たとえば、ビューがテーブルで SELECT * として定義されている場合、後でテーブルに追加された新しいカラムはビューの一部にならず、テーブルから削除されたカラムはビューからの選択時にエラーになります。

ALGORITHM 句は、MySQL によるビューの処理方法に影響を与えます。 DEFINER および SQL SECURITY 句は、ビューの呼び出し時にアクセス権限を確認するときに使用されるセキュリティーコンテキストを指定します。 WITH CHECK OPTION 句を指定すると、ビューによって参照されているテーブル内の行への挿入または更新を制約できます。 これらの句については、このセクションのあとの方で説明されています。

CREATE VIEW ステートメントには、このビューに対する CREATE VIEW 権限と、SELECT ステートメントによって選択される各カラムに対する何らかの権限が必要です。 SELECT ステートメントの他の場所で使用されるカラムの場合は、SELECT 権限が必要です。 OR REPLACE 句が存在する場合は、このビューに対する DROP 権限も必要です。 DEFINER 句が存在する場合、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、必要な権限は user の値によって異なります。

ビューが参照されると、このセクションのあとの方で説明されている権限確認が発生します。

ビューはデータベースに属します。 デフォルトでは、新しいビューはデフォルトデータベース内に作成されます。 特定のデータベースでビューを明示的に作成するには、db_name.view_name 構文を使用して、ビュー名をデータベース名で修飾します:

CREATE VIEW test.v AS SELECT * FROM t;

SELECT ステートメントの修飾されていないテーブルまたはビューの名前も、デフォルトのデータベースに関して解釈されます。 ビューは、テーブル名またはビュー名を適切なデータベース名で修飾することで、他のデータベース内のテーブルまたはビューを参照できます。

データベース内で、ベーステーブルとビューは同じ名前空間を共有するため、ベーステーブルとビューが同じ名前を持つことはできません。

SELECT ステートメントによって取得されるカラムは、テーブルのカラムへの単純な参照、または関数、定数値、演算子などを使用する式です。

ビューには、実テーブルと同様に、重複のない一意のカラム名が必要です。 デフォルトでは、SELECT ステートメントによって取得されるカラムの名前はビューカラム名に使用されます。 ビューカラムの明示的な名前を定義するには、カンマ区切りの識別子のリストとしてオプションの column_list 句を指定します。 column_list 内の名前の数は、SELECT ステートメントによって取得されるカラムの数と同じである必要があります。

ビューは、多くの種類の SELECT ステートメントから作成できできます。 ベーステーブルまたはほかのビューを参照できます。 結合、UNION、およびサブクエリーを使用できます。 SELECT では、テーブルを参照する必要もありません:

CREATE VIEW v_today (today) AS SELECT CURRENT_DATE;

次の例では、別のテーブルから 2 つのカラムを選択するビューと、それらのカラムから計算された式を定義します:

mysql> CREATE TABLE t (qty INT, price INT);
mysql> INSERT INTO t VALUES(3, 50);
mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
mysql> SELECT * FROM v;
+------+-------+-------+
| qty  | price | value |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+

ビュー定義は、次の制限に従います。

  • SELECT ステートメントは、システム変数またはユーザー定義変数を参照できません。

  • ストアドプログラム内では、SELECT ステートメントはプログラムパラメータまたはローカル変数を参照できません。

  • SELECT ステートメントは、準備済みステートメントのパラメータを参照できません。

  • この定義で参照されているテーブルまたはビューは、すべて存在する必要があります。 ビューの作成後に、定義が参照するテーブルまたはビューを削除すると、ビューを使用するとエラーになります。 この種類の問題に関してビュー定義を確認するには、CHECK TABLE ステートメントを使用します。

  • この定義は TEMPORARY テーブルを参照できないため、TEMPORARY ビューは作成できません。

  • トリガーをビューに関連付けることはできません。

  • SELECT ステートメント内のカラム名のエイリアスは (256 文字の別名の最大の長さではなく) 64 文字のカラムの最大の長さに対してチェックされます。

ORDER BY はビュー定義内で許可されていますが、独自の ORDER BY を含むステートメントを使用しているビューから選択した場合は無視されます。

この定義内のその他のオプションまたは句の場合は、そのビューを参照しているステートメントのオプションまたは句に追加されますが、その効果は定義されていません。 たとえば、ビュー定義に LIMIT 句が含まれているときに、独自の LIMIT 句を含むステートメントを使用しているビューから選択した場合、どの制限が適用されるかは未定義です。 これと同じ原則が、SELECT キーワードの後に続くオプション (ALLDISTINCTSQL_SMALL_RESULT など)、および INTO, FOR UPDATE, FOR SHARE, LOCK IN SHARE MODEPROCEDURE などの句にも適用されます。

システム変数を変更してクエリー処理環境を変更すると、ビューから取得した結果が影響を受ける可能性があります:

mysql> CREATE VIEW v (mycol) AS SELECT 'abc';
Query OK, 0 rows affected (0.01 sec)

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| mycol |
+-------+
1 row in set (0.01 sec)

mysql> SET sql_mode = 'ANSI_QUOTES';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| abc   |
+-------+
1 row in set (0.00 sec)

DEFINER および SQL SECURITY 句は、そのビューを参照しているステートメントの実行時に、そのビューに対するアクセス権限を確認するときにどの MySQL アカウントを使用するかを決定します。 有効な SQL SECURITY 特性値は、DEFINER (デフォルト) および INVOKER です。 これらは、それぞれ、そのビューを定義したユーザーまたは呼び出したユーザーが必要な権限を持っている必要があることを示します。

DEFINER 句が存在する場合、user 値は'user_name'@'host_name'CURRENT_USER または CURRENT_USER() として指定された MySQL アカウントである必要があります。 許可される user 値は、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、保持する権限によって異なります。 表示セキュリティの詳細は、そのセクションも参照してください。

DEFINER 句を省略すると、デフォルトの定義者は CREATE VIEW ステートメントを実行するユーザーになります。 これは、明示的に DEFINER = CURRENT_USER を指定するのと同じです。

ビュー定義内では、CURRENT_USER 関数はデフォルトでビューの DEFINER 値を返します。 SQL SECURITY INVOKER 特性を使用して定義されたビューの場合、CURRENT_USER は、そのビューの呼び出し元のアカウントを返します。 ビュー内のユーザー監査については、セクション6.2.22「SQL ベースのアカウントアクティビティ監査」を参照してください。

SQL SECURITY DEFINER 特性を使用して定義されたストアドルーチン内で、CURRENT_USER は、そのルーチンの DEFINER 値を返します。 ビュー定義に CURRENT_USERDEFINER 値が含まれている場合は、これにより、このようなルーチン内で定義されたビューも影響を受けます。

MySQL では、次のような表示権限がチェックされます:

  • ビューの定義時に、ビュー作成者は、そのビューによってアクセスされるトップレベルのオブジェクトを使用するために必要な権限を持っている必要があります。 たとえば、ビュー定義がテーブルカラムを参照している場合、作成者は、その定義の選択リスト内の各カラムに対する何らかの権限と、その定義内の別の場所で使用されている各カラムに対する SELECT 権限を持っている必要があります。 この定義がストアドファンクションを参照している場合は、その関数を呼び出すために必要な権限のみを確認できます。 関数呼び出し時に必要な権限は、その関数が実行されるときにしか確認できません。別の呼び出しでは、その関数内の別の実行パスが選択される可能性があります。

  • ビューを参照するユーザーは、そのビューにアクセスするための適切な権限 (そのビューから選択するための SELECT や、そのビューに挿入するための INSERT など) を持っている必要があります。

  • ビューが参照されると、そのビューによってアクセスされるオブジェクトに対する権限が、SQL SECURITY 特性が DEFINER または INVOKER のどちらであるかに応じて、それぞれ、そのビューの DEFINER アカウントによって保持されている権限または呼び出し元に対して確認されます。

  • ビューへの参照によってストアドファンクションが実行される場合、その関数内で実行されるステートメントの権限確認は、その関数の SQL SECURITY 特性が DEFINER または INVOKER のどちらであるかによって異なります。 セキュリティー特性が DEFINER である場合、その関数は DEFINER アカウントの権限で実行されます。 この特性が INVOKER である場合、その関数は、そのビューの SQL SECURITY 特性によって決定される権限で実行されます。

例: あるビューがストアドファンクションに依存する可能性があり、さらにその関数がほかのストアドルーチンを呼び出す可能性があります。 たとえば、次のビューはストアドファンクション f() を呼び出します。

CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);

f() に次のようなステートメントが含まれているとします。

IF name IS NULL then
  CALL p1();
ELSE
  CALL p2();
END IF;

f() が実行されるとき、f() 内のステートメントを実行するために必要な権限を確認する必要があります。 これは、f() 内の実行パスに応じて、p1() または p2() に対する権限が必要であることを示します。 これらの権限は実行時に確認する必要があり、それらの権限を持っている必要のあるユーザーは、ビュー v と関数 f()SQL SECURITY 値によって決定されます。

ビューの DEFINER および SQL SECURITY 句は、標準 SQL への拡張です。 標準 SQL では、ビューは SQL SECURITY DEFINER のルールを使用して処理されます。 標準には、ビューの定義者 (これは、ビューのスキーマの所有者と同じです) はそのビューに対する該当する権限 (SELECT など) を取得し、またそれらを付与することができると記載されています。 MySQL にはスキーマの所有者という概念がないため、MySQL では定義者を識別するための句が追加されています。 DEFINER 句は、標準が備えている機能、つまり、だれがそのビューを定義したかについての永続的なレコードを備えることを目的とした拡張です。 DEFINER のデフォルト値がビュー作成者のアカウントになっているのはそのためです。

オプションの ALGORITHM 句は、標準 SQL への MySQL 拡張です。 これは、MySQL によるビューの処理方法に影響を与えます。 ALGORITHM は、MERGETEMPTABLE、または UNDEFINED の 3 つの値を受け取ります。 詳細は、セクション25.5.2「ビュー処理アルゴリズム」 および セクション8.2.2.4「マージまたは実体化を使用した導出テーブル、ビュー参照および共通テーブル式の最適化」 を参照してください。

いくつかのビューは更新可能です。 つまり、これらのビューを UPDATEDELETEINSERT などのステートメントで使用して、ベースとなるテーブルの内容を更新できます。 ビューが更新可能であるためには、そのビュー内の行とベースとなるテーブル内の行の間に 1 対 1 の関係が存在する必要があります。 また、ビューを更新不可能にするその他の特定の構造構文も存在します。

ビュー内の生成されたカラムは、割り当て可能であるため、更新可能とみなされます。 ただし、このようなカラムが明示的に更新される場合、許可される値は DEFAULT のみです。 生成されるカラムの詳細は、セクション13.1.20.8「CREATE TABLE および生成されるカラム」 を参照してください。

更新可能なビューに対して WITH CHECK OPTION 句を指定すると、select_statement 内の WHERE 句が true である行を除く行への挿入または更新を回避できます。

更新可能なビューに対する WITH CHECK OPTION 句では、そのビューが別のビューとの関連で定義されている場合、LOCAL および CASCADED キーワードによってチェックテストのスコープが決定されます。 LOCAL キーワードは、CHECK OPTION を、定義されているビューのみに制限します。 CASCADED を指定すると、ベースとなるビューに対するチェックも評価されます。 どちらのキーワードも指定されていない場合、デフォルトは CASCADED になります。

更新可能なビューおよび WITH CHECK OPTION 句の詳細は、セクション25.5.3「更新可能および挿入可能なビュー」, and セクション25.5.4「WITH CHECK OPTION 句の表示」 を参照してください。


関連キーワード:  ステートメント, CREATE, 定義, TABLE, テーブル, 参照, 権限, カラム, DEFINER, 関数