CREATE MATERIALIZED VIEW
適用対象: Databricks SQL
"具体化されたビュー" は、クエリに使用できる事前計算済みの結果が含まれ、更新によって入力の変更を反映させることができるビューです。 具体化されたビューが更新されるたびに、クエリ結果が再計算され、アップストリームのデータセットの変更が反映されます。 具体化されたビューはすべて、DLT パイプラインによってサポートされます。 具体化されたビューは、手動で、またはスケジュールに従って更新できます。
手動更新を実行する方法の詳細については、「REFRESH (MATERIALIZED VIEW または STREAMING TABLE)を参照してください。
更新をスケジュールする方法の詳細については、「例の または ALTER MATERIALIZED VIEW」を参照してください。
具体化されたビューは、Pro または Serverless SQL ウェアハウスを使用するか、Delta Live Tables パイプライン内でのみ作成できます。
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 ランタイム チャネルを参照してください。 スケジュール [ REFRESH ] スケジュール条項
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 every day.
-- Note: All columns in a GROUP BY need to be explicitly aliased
> CREATE MATERIALIZED VIEW daily_sales
COMMENT 'Daily sales numbers'
SCHEDULE EVERY 1 DAY
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;