ビューは、1 つ以上のテーブルに対するクエリの結果から構築される仮想テーブルです。実際のデータは格納しません。ビューを使用すると、複雑なクエリを簡素化し、データセキュリティを強化できます。このトピックでは、CREATE VIEW ステートメントを使用してビューを作成する方法について説明します。
注意事項
AnalyticDB for MySQL のビューの動作は、MySQL のビューの動作と互換性があり、以下のとおりです。
-
3.1.9.0 より前のバージョン
AnalyticDB for MySQL クラスターは、MySQL のデフォルトの動作をサポートしていません。ビューの列を追加または削除した後、
SELECT * FROM <view_name>;を使用してビューにクエリを実行すると、その動作は MySQL とは一致しません。システムは列数の不一致を検出し、ビューが利用不可であると判断します。この場合、次のエラーが返されます:View '<view_name>' is stale; it must be re-created。 -
V3.1.9.0 以降
AnalyticDB for MySQL クラスターは、MySQL のデフォルトの動作をサポートしています。ビューを作成する際、クラスターは SQL ステートメント内の
*を明示的な列に展開してから、その SQL ステートメントを保存します。その後、列を追加または削除しても、ビューは影響を受けなくなります。
したがって、V3.1.9.0 以降を実行するクラスターを使用してビューを作成することを推奨します。これにより、MySQL のデフォルト動作との互換性が確保され、ビューで * を使用することによって引き起こされる予期しないセマンティクスやエラーを回避できます。
Data Lakehouse Edition クラスターのマイナーバージョンを表示するには、SELECT adb_version(); を実行します。マイナーバージョンをアップグレードするには、テクニカルサポートにお問い合わせください。
V3.1.9.0 以降を実行し、MySQL の動作と互換性がある AnalyticDB for MySQL クラスターでは、特殊なケースで副作用が発生する可能性があります。 たとえば、列の名前を C から D に変更し、ビューが列 A、B、および C を正確に参照する必要がある場合、列 C が存在しなくなるため、ビューは使用不可になり、エラーが返されます。 これは想定どおりの動作です。 列プルーニングは最適化フェーズで行われるのに対し、SQL 構文チェックと権限検証は解析フェーズで行われるため、クエリが最終的に列 C を使用しない場合でもエラーが返されます。 しかし、3.1.9.0 より前のバージョンでは、ビューの列数のみがチェックされ、その数は名前変更操作後も同じままであり、現在の * によって参照される列数も一貫しているため、すべてのチェックに合格し、エラーは返されません。 ビューの可用性チェックに合格すると、列 C はベーステーブルの順序で 3 番目の列にマッピングされます。 名前変更操作後に列 C をクエリしてもエラーは返されず、クエリ結果は予期しないものになります。
3.1.9.0 より前のバージョンを実行する AnalyticDB for MySQL クラスターの特殊な動作が業務で必要な場合は、ビューの作成時に特定のヒントを追加するか、設定を構成することで、期待される動作を実現できます。
-
単一のビューを設定するには、
/*+LOG_VIEW_SELECT_ASTERISK_MYSQL_MODE=false*/を追加します。次の例は、ヒントの追加方法を示しています:/*+LOG_VIEW_SELECT_ASTERISK_MYSQL_MODE=false*/ CREATE VIEW v0 AS SELECT * FROM base0; -
クラスター内のすべてのビューを設定するには、次のステートメントを実行します:
SET ADB_CONFIG LOG_VIEW_SELECT_ASTERISK_MYSQL_MODE = false;
構文
CREATE
[OR REPLACE]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name
AS select_statement;
|
パラメーター |
必須 |
説明 |
|
|
いいえ |
同じ名前のビューが存在するかどうかに応じて、次のルールでビューを作成します:
説明
このパラメーターが指定されておらず、同じ名前のビューが存在する場合、ビューの作成は失敗します。 |
|
|
ビューのデータをクエリするときに使用されるセキュリティ検証メソッドです。有効な値は次のとおりです:
説明
|
|
|
|
はい |
ビューの名前。 説明
ビュー名の前に |
|
|
ビューのデータソース。 |
例
-
テストデータの準備
AnalyticDB for MySQL クラスターの特権アカウントを使用して、次の操作を実行します:
-
user1という名前のアカウントを作成します:CREATE USER user1 IDENTIFIED BY 'user1_pwd'; -
adb_demoという名前のデータベースと、そのデータベース内にt1という名前のテーブルを作成します。次のステートメントは、t1テーブルを作成します:Create Table `t1` ( `id` bigint AUTO_INCREMENT, `id_province` bigint NOT NULL, `user_info` varchar, primary key (`id`) ) DISTRIBUTED BY HASH(`id`);t1テーブルにテストデータを挿入します:INSERT INTO t1(id_province,user_info) VALUES (1,'Tom'),(1,'Jerry'),(2,'Jerry'),(3,'Mark');
-
-
ビューの作成
説明次の例では、
t1テーブルを基に異なるセキュリティ検証メソッドでビューを作成し、DEFINERとINVOKERにおける権限の違いを説明します。-
v1という名前のビューを作成し、SQL SECURITYをINVOKERに設定するには、次のステートメントを実行します:CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT id_province,user_info FROM t1 WHERE id_province=1; -
v2という名前のビューを作成し、SQL SECURITYをDEFINERに設定するには、次のステートメントを実行します:CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT id_province,user_info FROM t1 WHERE id_province=1; -
v3という名前のビューをSQL SECURITYを指定せずに作成する (この場合、システムはデフォルトでINVOKERを使用します) には、次のステートメントを実行します:CREATE VIEW v3 AS SELECT id_province,user_info FROM t1 WHERE id_province=1;
-
-
権限の比較
-
特権アカウントを使用して、3 つのビューをクエリする権限のみを
user1に付与します:GRANT SELECT ON adb_demo.v1 TO 'user1'@'%'; GRANT SELECT ON adb_demo.v2 TO 'user1'@'%'; GRANT SELECT ON adb_demo.v3 TO 'user1'@'%';この場合、
user1は AnalyticDB for MySQL クラスターのadb_demoデータベースに接続した後、v2ビューのみをクエリできます。 クエリ文:SELECT * FROM v2;次の結果が返されます:
+-------------+-----------+ | ID_PROVINCE | USER_INFO | +-------------+-----------+ | 1 | Tom | | 1 | Jerry | +-------------+-----------+ただし、
user1がv1またはv3ビューをクエリすると、エラーが返されます。クエリステートメント:SELECT * FROM v1または
SELECT * FROM v3どちらのステートメントも次のエラーを返します:
ERROR 1815 (HY000): [20049, 2021083110261019216818804803453927668] : Failed analyzing stored view -
user1に 3 つのビューをクエリする権限を付与した後、特権アカウントを使用してuser1にt1テーブルをクエリする権限を付与します:GRANT SELECT ON adb_demo.t1 to user1@'%';この場合、
user1が AnalyticDB for MySQL クラスターのadb_demoデータベースに接続すると、user1はすべてのv1、v2、およびv3ビューをクエリできます。 クエリ文:SELECT * FROM v1;または
SELECT * FROM v2;または
SELECT * FROM v3;3 つのクエリステートメントはすべて同じ結果を返します:
+-------------+-----------+ | ID_PROVINCE | USER_INFO | +-------------+-----------+ | 1 | Tom | | 1 | Jerry | +-------------+-----------+
-
よくある質問
ベーステーブルで小文字で定義された列名が、ビューの結果セットで大文字で表示されるのはなぜですか?
AnalyticDB for MySQL のビュー結果セットの列名は、デフォルトでは大文字と小文字が区別されません。ビュー結果セットの列名を小文字にしたい場合は、VIEW_OUTPUT_NAME_CASE_SENSITIVE の値を true に設定して、大文字と小文字を区別するように指定できます。そのためには、次のステートメントを実行します。
SET ADB_CONFIG VIEW_OUTPUT_NAME_CASE_SENSITIVE=true;
ベストプラクティス
詳細については、「ビューを使用した権限管理」をご参照ください。