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 VIEW
は CREATE 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
キーワードの後に続くオプション (ALL
、DISTINCT
、SQL_SMALL_RESULT
など)、および INTO
, FOR UPDATE
, FOR SHARE
, LOCK IN SHARE MODE
、PROCEDURE
などの句にも適用されます。
システム変数を変更してクエリー処理環境を変更すると、ビューから取得した結果が影響を受ける可能性があります:
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_USER
の DEFINER
値が含まれている場合は、これにより、このようなルーチン内で定義されたビューも影響を受けます。
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
は、MERGE
、TEMPTABLE
、または UNDEFINED
の 3 つの値を受け取ります。 詳細は、セクション25.5.2「ビュー処理アルゴリズム」 および セクション8.2.2.4「マージまたは実体化を使用した導出テーブル、ビュー参照および共通テーブル式の最適化」 を参照してください。
いくつかのビューは更新可能です。 つまり、これらのビューを UPDATE
、DELETE
、INSERT
などのステートメントで使用して、ベースとなるテーブルの内容を更新できます。 ビューが更新可能であるためには、そのビュー内の行とベースとなるテーブル内の行の間に 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 句の表示」 を参照してください。