従来の APIs でデータ分類を使用する¶
このトピックでは、Snowflakeの従来の APIs でデータを分類する例を示します: EXTRACT_SEMANTIC_CATEGORIES および ASSOCIATE_SEMANTIC_CATEGORY_TAGS。これらの APIs は、 データ分類 の更新に合わせて更新されなくなりました。
これらの APIs は引き続き使用できます。ただし、 データ分類を使用する に示されるアプローチを使用するように、ワークフローを更新する必要があります。
このトピックの内容:
概要¶
データを分類する次の例は、スコープに基づいてさまざまなユースケースに対応しています。
初めて分類を使用する場合は、単一のテーブルの分類から始めてから、他の2つの例に進んでください。
共通テーブルおよびロール¶
このトピックの例では、以下に示すテーブルとカスタムロールを使用しています。
テーブル: 従業員に関するデータが含まれている
my_db.my_schema.hr_data
。ロール:
data_engineer
: テーブルを分類します。policy_admin
: マスキングポリシーで個人情報を保護します。analyst
: アクセスを制限する必要がある可能性のあるロールの例です。例では、このロールが存在することを前提としています。-
GOVERNANCE_ADMIN: 分類システムタグを割り当てます。
GOVERNANCE_VIEWER: タグとマスキングポリシーに関連するAccount Usageビューをクエリします。
テーブルを作成します。
CREATE OR REPLACE TABLE hr_data ( age INTEGER, email_address VARCHAR, fname VARCHAR, lname VARCHAR );
テーブルをロードします(詳細表示なし)。
カスタムロールを作成し、それらのロールに必要な権限を付与します。
分類プロセスを実行するには、
data_engineer
ロールがテーブルにアクセスする必要があります。ロールをデータベースロールに切り替えることはできないため、この例では GOVERNANCE_ADMIN データベースロールをdata_engineer
ロールに付与することに注意してください。use role accountadmin; create role data_engineer; grant usage on database my_db to role data_engineer; grant usage on schema my_db.my_schema to role data_engineer; grant select, update on table my_db.my_schema.hr_data to role data_engineer; grant database role snowflake.governance_admin to role data_engineer;
policy_admin
カスタムロールは、 PII データを含むすべての列にマスキングポリシーを割り当てる必要があります。use role accountadmin; create role policy_admin; grant apply masking policy on account to role policy_admin; grant database role snowflake.governance_viewer to role policy_admin;
単一のテーブルを分類する¶
単一のテーブルの例は、3段階の分類プロセス(つまり、分析、確認、適用)を拡張して結果を適用し、 analyst
カスタムロールからのテーブルアクセスを取り消します。
ステップ1: テーブル列を分類する¶
このステップでは、 data_engineer
が分類プロセスを実行し、 policy_admin
が マスキングポリシー で列データを保護します。
分析:
data_engineer
カスタムロールを使用して EXTRACT_SEMANTIC_CATEGORIES 関数を呼び出し、my_db.my_schema.hr_data
という名前のテーブルの列を分類します。USE ROLE data_engineer; SELECT EXTRACT_SEMANTIC_CATEGORIES('my_db.my_schema.hr_data');
レビュー: データエンジニアが結果をレビューして、結果が意味を成すことを確認します。
適用: データエンジニアは、分類システムタグを列に割り当てます。
データエンジニアには、自動割り当てと手動割り当ての2つのオプションがあります。
システムタグを自動的に割り当てるには、 ASSOCIATE_SEMANTIC_CATEGORY_TAGS ストアドプロシージャを呼び出します。ノート:
テーブルの完全修飾名と最初のステップの関数は、ストアドプロシージャの引数です。
ストアドプロシージャは EXTRACT_SEMANTIC_CATEGORIES 関数を再実行します。最初のステップの結果を保持する場合は、ストアドプロシージャを呼び出す前に結果をテーブルに保存します。
CALL ASSOCIATE_SEMANTIC_CATEGORY_TAGS( 'my_db.my_schema.hr_data', EXTRACT_SEMANTIC_CATEGORIES('my_db.my_schema.hr_data') );
ストアドプロシージャが正常に実行されると、次のようなメッセージが返されます。
Applied tag semantic_category to <n> columns. Applied tag privacy_category to <n> columns.
それ以外の、ストアドプロシージャが実行されない場合や、必要に応じて分類システムタグを手動で各列に割り当てることが決定された場合は、 ALTER TABLE ... ALTER COLUMN ステートメントを使用します。たとえば、いずれかのシステムタグを FNAME 列(つまり、名)に割り当てます。
USE ROLE data_engineer; ALTER TABLE my_db.my_schema.hr_data MODIFY COLUMN fname SET TAG SNOWFLAKE.CORE.SEMANTIC_CATEGORY='NAME';
または
ALTER TABLE my_db.my_schema.hr_data MODIFY COLUMN fname SET TAG SNOWFLAKE.CORE.PRIVACY_CATEGORY='IDENTIFIER';
ステップ2: テーブル列を保護する¶
このステップでは、 my_db.my_schema.hr_data
テーブルのいくつかの列に PRIVACY_CATEGORY = 'IDENTIFIER'
タグが割り当てられており、これらの列をマスキングポリシーで保護する必要があることを前提としています。
これらの列を保護するには、
policy_admin
ロールを使用して、 IDENTIFIER プライバシータグが適用されている列を検索します。USE ROLE policy_admin; SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES WHERE TAG_NAME = 'PRIVACY_CATEGORY' AND TAG_VALUE = 'IDENTIFIER';
TAG_REFERENCES ビューの遅延は、最大120分間です。より早く結果が必要で、分類タグをクエリする列の名前がわかっている場合は、代わりに TAG_REFERENCES または TAG_REFERENCES_ALL_COLUMNS テーブル関数を使用できます。
policy_admin
ロールを使用して、適切な列にマスキングポリシーを適用します。たとえば、次のステートメントはidentifier_mask
マスキングポリシーをfname
列に適用します。ALTER TABLE my_db.my_schema.hr_data MODIFY COLUMN fname SET MASKING POLICY governance.policies.identifier_mask;
スキーマ内にあるすべてのテーブルを分類する¶
この例は、2つのユーザー定義のストアドプロシージャを使用して、スキーマ内にあるすべてのテーブルを分類する方法を示しています。
classify_schema
: スキーマ内のすべてのテーブルをリストし、分類結果を格納するテーブルを作成してから、分類タグを各テーブルから抽出して結果テーブルに格納します。associate_tag_batch
:classify_schema
ストアドプロシージャの結果を使用して、分類システムタグをスキーマ内のすべてのテーブル列に自動的に割り当て、各テーブルに割り当てられたタグの数を返します。
重要
classify_schema
という名前のストアドプロシージャは、結果を格納する仮テーブルを作成します。仮テーブルは、このストアドプロシージャを呼び出すユーザーのユーザーセッションの期間中、存在します。ユーザーセッションが期限切れになると、Snowflakeは仮テーブルをドロップするため、ユーザーはストアドプロシージャを再度呼び出して、仮テーブルを再作成する必要があります。
仮テーブルを保持する必要がある場合は、 sqlText
コマンドから temp
キーワードを削除してテーブルを作成します。
詳細については、 CREATE TABLE コマンドにある TEMP[ORARY]
オプションをご参照ください。
classify_schema
という名前の最初のプロシージャを作成します。create or replace procedure classify_schema(schema_name string, result_table string) returns object language JavaScript as $$ // 1 const table_names = snowflake.execute({ sqlText: `show terse tables in schema identifier(?)`, binds: [SCHEMA_NAME], }); // helper function for quoted table names function quote(name) { return '"'+ name.replace(/"/g,'""') + '"'; } // create table to store results in. if it already exists, we will add to it rather than overwrite snowflake.execute({ sqlText: `create temp table if not exists identifier(?) (table_name string, result variant)`, binds: [RESULT_TABLE], }) // loop through tables while (table_names.next()) { let name = table_names.getColumnValue('name'); // add schema to table name name = SCHEMA_NAME + "." + quote(name); // insert qualified table name and result into result table const results = snowflake.execute({ sqlText: `insert into identifier(?) select ?, extract_semantic_categories(?)`, binds: [RESULT_TABLE, name, name], }); } // return the number of tables classified return {tables_classified: table_names.getRowCount()}; $$;
associate_tag_batch
という名前の2番目のプロシージャを作成します。create or replace procedure associate_tag_batch(result_table string) returns Object language JavaScript as $$ // get table names and classification results to loop through const tags_to_apply = snowflake.execute({ sqlText: `select table_name, result from identifier(?)`, binds: [RESULT_TABLE], }); const out = {}; while (tags_to_apply.next()) { // get table name const name = tags_to_apply.getColumnValue('TABLE_NAME'); // get classification result const classification_results = tags_to_apply.getColumnValue('RESULT'); // call associate semantic category tags with table name and classification result const results = snowflake.execute({ sqlText: `call associate_semantic_category_tags(?, parse_json(?))`, binds: [name, JSON.stringify(classification_results)], }); results.next(); out[name] = results.getColumnValue(1).split('\n'); } // return number of tags applied per table return out; $$;
分類するスキーマの名前と、各テーブルの EXTRACT_SEMANTIC_CATEGORY の結果を引数として保持する仮テーブルの名前を使用して、
classify_schema
ストアドプロシージャを呼び出します。call classify_schema('my_db.my_schema','my_temporary_classification_table');
仮テーブルの結果を確認し、必要に応じて変更します。
結果が十分な場合は、
associate_tag_batch
ストアドプロシージャを呼び出して、分類システムタグをテーブル列に割り当てます。call associate_tag_batch('my_temporary_classification_table');
データベース内にあるすべてのテーブルを分類する¶
この例は、2つのストアドプロシージャを使用して、データベース内にあるすべてのテーブルを分類する方法を示しています。
classify_database
: データベース内のスキーマごとにスキーマ内のすべてのテーブルを分類し、分類されたテーブルの数とスキーマの数を返します。associate_tag_batch
: スキーマ内にあるすべてのテーブルを分類する (このトピック内)で定義されているものと同じ操作を実行します。
classify_database
ストアドプロシージャを作成します。create or replace procedure classify_database(database_name string, result_table string) returns Object language JavaScript as $$ // get list of schemas in database const schema_names = snowflake.execute({ sqlText: `show terse schemas in database identifier(?)`, binds: [DATABASE_NAME], }); // helper function for quoted schema names function quote(name) { return '"'+ name.replace(/"/g,'""') + '"'; } // counter for tables. will use result from classify_schema to increment let table_count = 0 while (schema_names.next()) { let name = schema_names.getColumnValue('name'); // skip the information schema if (name == "INFORMATION_SCHEMA") { continue; } // add database name to schema name = DATABASE_NAME + "." + quote(name); // call classify_schema on each schema. This will loop over tables in schema const results = snowflake.execute({ sqlText: `call classify_schema(?, ?)`, binds: [name, RESULT_TABLE], }); results.next(); // increment total number of tables by the number of tables in the schema table_count += results.getColumnValue(1).tables_classified ; } return { tables_classified: table_count, // subtract one from number of schemas because we skip the information schema schemas_classified: schema_names.getRowCount() - 1, }; $$;
分類するデータベースの名前と仮テーブルの名前を使用して
classify_database
ストアドプロシージャを呼び出し、データベースの各スキーマに結果を保存します。call classify_database('my_db','my_temporary_classification_table');
各スキーマに移動して、仮テーブルを確認し、必要に応じて修正します。
結果が十分な場合は、 各 スキーマに対して
associate_tag_batch
ストアドプロシージャを1回呼び出し、そのスキーマのテーブルにタグを適用します。たとえば、データベースに3つのスキーマが含まれている場合は、ストアドプロシージャを3回呼び出します。call associate_tag_batch('my_temporary_classification_table');