CREATE MATERIALIZED VIEW
適用対象: Databricks SQL
"具体化されたビュー" は、クエリに使用できる事前計算済みの結果が含まれ、更新によって入力の変更を反映させることができるビューです。 具体化されたビューが更新されるたびに、クエリ結果が再計算され、アップストリームのデータセットの変更が反映されます。 具体化されたビューはすべて、DLT パイプラインによってサポートされます。 具体化されたビューは、手動で、またはスケジュールに従って更新できます。
手動による更新を実行する方法の詳細については、「REFRESH (MATERIALIZED VIEW または STREAMING TABLE)」を参照してください。
更新をスケジュールする方法の詳細については、「例」または「ALTER MATERIALIZED VIEW」を参照してください。
Note
具体化されたビューとストリーミング テーブルに対する作成および更新操作は、サーバーレス Delta Live Tables パイプラインを利用します。 カタログ エクスプローラーを使用して、UI のバッキング パイプラインの詳細を表示できます。 「カタログ エクスプローラーとは」を参照してください。
構文
{ CREATE OR REPLACE MATERIALIZED VIEW | CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] }
view_name
[ column_list ]
[ view_clauses ]
[schedule_clause]
AS query
column_list
( { column_name column_type column_properties } [, ...]
[ , table_constraint ] [...])
column_properties
{ NOT NULL | COMMENT column_comment | column_constraint | MASK clause } [ ... ]
view_clauses
{ PARTITIONED BY (col [, ...]) |
COMMENT view_comment |
TBLPROPERTIES clause |
SCHEDULE [ REFRESH ] schedule_clause |
WITH { ROW FILTER clause } } [...]
schedule_clause
{ EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS } |
CRON cron_string [ AT TIME ZONE timezone_id ] }
パラメーター
REPLACE
指定すると、ビューとその内容が既に存在する場合に置き換えられます。
IF NOT EXISTS
ビューが存在しない場合、作成します。 この名前のビューが既に存在する場合、
CREATE MATERIALIZED VIEW
ステートメントは無視されます。IF NOT EXISTS
かOR REPLACE
のいずれか 1 つだけを指定できます。-
新しく作成されたビューの名前。 完全修飾のビュー名は一意にする必要があります。
column_list
必要に応じて、ビューのクエリ結果内の列にラベルを付けます。 列の一覧を指定する場合は、列の別名の数がクエリ内の式の数と一致している必要があります。 列リストが指定されていない場合、別名はビューの本体から引き出されます。
-
列名は一意で、クエリの出力列にマップする必要があります。
column_type
列のデータ型を指定します。 Azure Databricks でサポートされているすべてのデータ型が、具体化されたビューでサポートされているわけではありません。
column_comment
列の名前について説明する、省略可能な
STRING
リテラル。 このオプションは、column_type
と共に指定する必要があります。 列タイプが指定されていない場合、列コメントはスキップされます。column_constraint
情報主キーまたは情報外部キーの制約を具体化されたビューの列に追加します。 列タイプが指定されていない場合、列の制約はスキップされます。
-
重要
この機能はパブリック プレビュー段階にあります。
列マスク関数を追加して、機密データを匿名化します。 その列からの後続のすべてのクエリは、列の元の値の代わりに、列に対してその関数の評価結果を受け取ります。 これは、関数が呼び出し元ユーザーの ID またはグループ メンバーシップを検査して、値を編集するかどうかを決定できる、きめ細かいアクセス制御に役立ちます。 列タイプが指定されていない場合、列マスクはスキップされます。
-
table_constraint
情報主キーまたは情報外部キーの制約を具体化されたビューのテーブルに追加します。 列タイプが指定されていない場合、テーブル制約はスキップされます。
view_clauses
必要に応じて、パーティション分割、コメント、ユーザー定義プロパティ、新しい具体化されたビューの更新スケジュールを指定します。 各サブ句は、1 回だけ指定できます。
-
テーブルをパーティション分割するための、テーブルの列の省略可能な一覧。
COMMENT view_comment
テーブルについて説明する
STRING
リテラル。-
必要に応じて、1 つ以上のユーザー定義プロパティを設定します。
この設定を使用して、このステートメントの実行に使用する Delta Live Tables ランタイム チャネルを指定します。
pipelines.channel
プロパティの値を"PREVIEW"
または"CURRENT"
に設定します。 既定値は"CURRENT"
です。 Delta Live Tables チャネルの詳細については、「 Delta Live Tables ランタイム チャネルを参照してください。 SCHEDULE [ REFRESH ] schedule_clause
EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS }
重要
この機能はパブリック プレビュー段階にあります。
定期的に更新をスケジュールするには、
EVERY
構文を使用します。EVERY
構文が指定されている場合、ストリーミング テーブルまたは具体化されたビューは、指定された値 (HOUR
、HOURS
、DAY
、DAYS
、WEEK
、WEEKS
など) に基づいて、指定した間隔で定期的に更新されます。 次の表に、number
に使用できる整数値を示します。Time unit 整数値 HOUR or HOURS
1 <= H <= 72 DAY or DAYS
1 <= D <= 31 WEEK or WEEKS
1 <= W <= 8 Note
含まれる時間単位の単数形と複数形は、意味的に同等です。
CRON cron_string [ AT TIME ZONE timezone_id ]
quartz cron 値を使用して更新をスケジュールします。 有効な time_zone_values が受け入れられます。
AT TIME ZONE LOCAL
はサポートされません。AT TIME ZONE
が存在しない場合は、セッション タイム ゾーンが使用されます。AT TIME ZONE
が存在せず、セッション タイム ゾーンも設定されていない場合は、エラーがスローされます。SCHEDULE
は意味的にSCHEDULE REFRESH
と同等です。
WITH ROW FILTER 句
重要
この機能はパブリック プレビュー段階にあります。
行フィルター関数をテーブルに追加します。 そのテーブルからの後続のすべてのクエリは、関数がブール値 TRUE に評価する行のサブセットを受け取ります。 これは、関数が呼び出し元ユーザーの ID またはグループ メンバーシップを検査して、特定の行をフィルター処理するかどうかを決定できる、きめ細かいアクセス制御に役立ちます。
-
AS クエリ
ベース テーブルまたはその他のビューからビューを構築するクエリです。
必要なアクセス許可
具体化されたビュー (MV) を作成するユーザーは、MV の所有者であり、次のアクセス許可が必要です。
- MV で参照されるベース テーブルに対する
SELECT
特権。 - 親カタログに対する
USE CATALOG
権限と親スキーマに対するUSE SCHEMA
権限。 - MV のスキーマに対する
CREATE MATERIALIZED VIEW
特権。
ユーザーが MV を更新できるようにするには、次のものが必要です。
- 親カタログに対する
USE CATALOG
権限と親スキーマに対するUSE SCHEMA
権限。 - MV の所有権または MV に対する
REFRESH
特権。 - MV の所有者は、MV で参照されるベース テーブルに対する
SELECT
特権を持っている必要があります。
ユーザーが MV のクエリを実行できるようにするには、次のものが必要です。
- 親カタログに対する
USE CATALOG
権限と親スキーマに対するUSE SCHEMA
権限。 - 具体化されたビューに対する
SELECT
特権。
行フィルターと列マスク
重要
この機能はパブリック プレビュー段階にあります。
行フィルターを使用すると、テーブル スキャンで行がフェッチされるたびにフィルターとして適用される関数を指定できます。 これらのフィルターにより、後続のクエリでフィルター述語が true と評価される行のみが返されるようになります。
列マスクを使用すると、テーブル スキャンで行がフェッチされるたびに列の値をマスクできます。 その列に関連する今後のすべてのクエリでは、列の元の値を置き換えて、列に対してその関数を評価した結果が返されます。
行フィルターと列マスクの使用方法の詳細については、「行フィルターと列マスクを使って機密性の高いテーブル データをフィルター処理する」を参照してください。
行フィルターと列マスクの管理
具体化されたビューの行フィルターと列マスクは、CREATE
ステートメントを通じて追加する必要があります。
Behavior
- 定義者として更新:
REFRESH MATERIALIZED VIEW
ステートメントが具体化されたビューを更新すると、行フィルター関数は定義者の権限で (テーブル所有者として) 実行されます。 つまり、テーブルの更新では、具体化されたビューを作成したユーザーのセキュリティ コンテキストが使用されます。 - クエリ: ほとんどのフィルターは定義者の権限で実行されますが、ユーザー コンテキストをチェックする関数 (
CURRENT_USER
やIS_MEMBER
など) は例外です。 これらの関数は呼び出し元として実行されます。 このアプローチでは、現在のユーザーのコンテキストに基づいて、ユーザー固有のデータ セキュリティとアクセス制御が適用されます。 - 行フィルターと列マスクを含むソース テーブルに対する具体化されたビューを作成する場合、具体化されたビューの更新は常に完全更新になります。 完全更新では、最新の定義を使用して、ソースで使用可能なすべてのデータが再処理されます。 これにより、ソース テーブルのセキュリティ ポリシーが最新のデータと定義に基づいて評価され、適用されるようになります。
可観測性
DESCRIBE EXTENDED
、INFORMATION_SCHEMA
、またはカタログ エクスプローラーを使用して、特定の具体化されたビューに適用される既存の行フィルターと列マスクを調べます。 この機能により、ユーザーは具体化されたビューのデータ アクセスと保護対策を監査および確認できます。
制限事項
- NULL 許容列に対する
sum
集計を含む具体化されたビューに、その列から削除された最後の非 NULL 値があり、その列にNULL
値のみが残っている場合は、具体化されたビューの集計の結果の値としてNULL
ではなく 0 が返されます。 - 列参照には別名は必要ありません。 非列参照式には、次の例のように、別名が必要です。
- 可能:
SELECT col1, SUM(col2) AS sum_col2 FROM t GROUP BY col1
- 不可:
SELECT col1, SUM(col2) FROM t GROUP BY col1
- 可能:
- 有効なステートメントにするには、
NOT NULL
をPRIMARY KEY
と共に手動で指定する必要があります。 - 具体化されたビューでは、ID 列や代理キーはサポートされていません。
- 具体化されたビューでは、
OPTIMIZE
およびVACUUM
コマンドはサポートされていません。 メンテナンスは自動的に行われます。 - 具体化されたビューでは、データ品質の制約を定義するための期待値はサポートされていません。
例
-- Create a materialized view if it doesn't exist
> CREATE MATERIALIZED VIEW IF NOT EXISTS subscribed_movies
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create and schedule a materialized view to be refreshed daily at midnight.
-- Note: All columns in a GROUP BY need to be explicitly aliased
> CREATE MATERIALIZED VIEW daily_sales
COMMENT 'Daily sales numbers'
SCHEDULE CRON '0 0 0 * * ? *'
AS SELECT date AS date, sum(sales) AS sumOfSales
FROM table1
GROUP BY date;
-- Sets the runtime channel to "PREVIEW"
> CREATE MATERIALIZED VIEW mv_preview
TBLPROPERTIES(pipelines.channel = "PREVIEW")
AS SELECT * FROM RANGE(10)
-- Create a materialized view with a table constraint
> CREATE MATERIALIZED VIEW IF NOT EXISTS subscribed_movies(
member_id int NOT NULL,
full_name string,
movie_title string,
CONSTRAINT movie_pk PRIMARY KEY(member_id)
)
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create or replace the materialized view to remove the table constraint and add a partition
> CREATE OR REPLACE MATERIALIZED VIEW subscribed_movies
PARTITIONED BY (member_id)
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create a materialized view with a row filter and a column mask
> CREATE MATERIALIZED VIEW masked_view (
id int,
name string,
region string,
ssn string MASK catalog.schema.ssn_mask_fn
)
WITH ROW FILTER catalog.schema.us_filter_fn ON (region)
AS SELECT id, name, region, ssn
FROM employees;