객체 종속성(Object Dependencies)
객체 종속성(Object Dependencies)
이 주제는 객체 종속성의 개념과 Account Usage 뷰 OBJECT_DEPENDENCIES와 관련된 정보를 제공해요.
본문
객체 종속성이란 무엇인가?
객체 종속성이란 객체에 대해 작업하려면 그 객체가 자신의 메타데이터를 참조하거나 다른 객체 하나 이상의 메타데이터를 참조해야 한다는 뜻이에요. Snowflake는 Account Usage 뷰 OBJECT_DEPENDENCIES에서 객체 종속성을 추적해요.
Snowflake는 로컬 Snowflake 계정의 객체 종속성과 공급자 공유를 통해 사용할 수 있는 테이블에서 소비자 계정에 뷰를 만드는 것 같은 데이터 공유와 관련된 특정 종속성을 지원해요. 공유 객체의 종속성은 데이터 담당자가 더 큰 데이터 무결성을 보장하고 각 규제 표준을 더 완전히 준수하며 더 상세한 영향 분석을 생성할 수 있게 해요.
Snowflake는 종속성을 촉발할 수 있는 다음 종속성 유형을 지원해요: 객체 *name* 값, 객체 ID 값, 그리고 객체 *name* 값과 객체 ID 값의 조합.
BY_NAME:
BY_NAME 종속성은 SQL 문이 객체 자체의 *name* 값을 지정할 때(예: CREATE 또는 ALTER 명령) 또는 객체가 SQL 작업을 완료하기 위해 다른 객체의 *name* 값을 호출할 때(예: FROM 절 사용) 발생해요. 예를 들어 다음 문장을 고려하세요:
create view myview as select * from mytable;
테이블 *name* 값 mytable은 테이블의 메타데이터예요. myview라는 뷰는 mytable이라는 테이블에 종속돼요. 뷰를 만들려면 테이블이 존재해야 해요. Snowflake는 myview라는 뷰를 참조 객체(referencing object)라고 하고 mytable 테이블을 참조 대상 객체(referenced object)라고 해요.
BY_ID:
BY_ID 종속성은 객체가 다른 객체의 객체 ID 값을 저장할 때 발생해요. ID 종속성의 한 예는 외부 스테이지가 스토리지 통합의 OBJECT_ID 값을 저장하는 경우예요. 현재 스토리지 통합 객체 ID 값은 Snowflake만 접근할 수 있으며 어떤 고객 대상 SQL 작업으로도 표시되지 않아요.
create stage my_ext_stage
url='s3://load/files/'
storage_integration = myint;
Snowflake는 my_ext_stage라는 외부 스테이지를 참조 객체라고 하고 myint라는 스토리지 통합을 참조 대상 객체라고 해요.
BY_NAME_AND_ID:
일부 Snowflake 객체(예: 구체화된 뷰)는 객체 *name* 값과 객체 ID 값 모두에 종속돼요. 이러한 객체는 종종 기존 객체를 대체하는 CREATE OR REPLACE 문이나 객체 이름을 바꾸는 ALTER 문의 결과예요. 자세한 내용은 Account Usage OBJECT_DEPENDENCIES 뷰의 사용 메모 섹션을 참조하세요.
지원되는 객체 종속성
Snowflake는 다음과 같이 참조 객체와 참조 대상 객체를 지원해요:
| 참조 객체 | 참조 대상 객체 | 종속성 유형 |
|---|---|---|
| 뷰, 보안 뷰, 동적 테이블, SQL UDF, SQL UDTF 및 이름으로 참조되는 기타 객체 | 뷰, 보안 뷰, 구체화된 뷰, 동적 테이블, UDF(모든 종류), UDTF 및 이름으로 참조되는 기타 객체 | BY_NAME |
| 외부 스테이지, 스트림 | 스토리지 통합, 테이블, 뷰, 보안 뷰 | BY_ID |
| 외부 테이블 | 스테이지 | BY_ID |
| 구체화된 뷰 | 테이블, 외부 테이블 | BY_NAME_AND_ID |
Snowflake는 데이터 공유 맥락에서 다음 객체만 지원한다는 점에 유의하세요:
| 참조 객체 | 참조 대상 객체 | 종속성 유형 |
|---|---|---|
| 뷰, 동적 테이블, SQL UDF, SQL UDTF | 테이블, 보안 뷰, 보안 구체화된 뷰, 동적 테이블, 보안 UDF 및 보안 UDTF | BY_NAME |
| 구체화된 뷰 | 테이블 | BY_NAME_AND_ID |
자세한 내용은 OBJECT_DEPENDENCIES 뷰의 사용 메모 섹션을 참조하세요.
이점
객체 종속성 식별은 다음과 같이 데이터 추적 사용 사례에 대한 인사이트를 제공해요:
- 영향 분석: 객체 종속성을 알면 데이터 관리자는 참조 객체와 참조 대상 객체 사이의 관계를 식별해 참조 대상 객체에 대한 업데이트가 참조 객체 사용자에게 부정적인 영향을 주지 않도록 할 수 있어요. 예를 들어 테이블 소유자가 테이블에 열을 추가할 계획이라고 가정하세요. 테이블 이름을 기준으로 OBJECT_DEPENDENCIES 뷰를 쿼리하면 영향을 받을 모든 객체(예: 뷰)가 반환돼요. 그런 다음 데이터 관리자는 테이블과 뷰 업데이트의 시점이 테이블에서 만든 뷰를 쿼리하는 사용자에게 부정적인 영향을 주는 깨진 쿼리를 초래하지 않도록 조치 계획을 조정할 수 있어요.
- 규정 준수: 객체 종속성 관계는 규정 준수 담당자가 민감 데이터 소스(즉, 참조 대상 객체)와 데이터 대상(즉, 참조 객체) 사이의 관계를 식별해준다. 그런 다음 규정 준수 담당자는 규정 준수 요구 사항(GDPR 등)에 따라 참조 대상 객체와 참조 객체를 업데이트하는 최선의 방법을 결정할 수 있어요.
- 데이터 무결성: 객체 종속성 관계는 분석가, 과학자, 규정 준수 담당자 및 기타 비즈니스 사용자 같은 주요 데이터 전문가가 데이터가 신뢰할 수 있는 소스에서 비롯됐다고 확신할 수 있게 해줘요.
제한 사항
뷰 사용 메모에 더해 OBJECT_DEPENDENCIES 뷰를 쿼리할 때 다음 제한 사항에 유의하세요:
- 세션 매개변수: Snowflake는 정의에 세션 매개변수를 포함하는 객체의 종속성을 정확히 계산할 수 없어요. 세션 매개변수는 컨텍스트에 따라 다른 값을 가질 수 있기 때문이에요. Snowflake는 뷰와 함수 정의에서 세션 변수를 사용하지 않는 것을 권장해요.
- Snowflake 구현: 이 뷰는 Snowflake 구현에 필요한 종속성을 포착하지 않아요. 예를 들어 이 뷰는 다른 테이블의 클론에서 새 테이블을 만드는 데 필요한 종속성을 기록하지 않아요.
- 객체 해석: 뷰 정의가 함수를 사용해 객체를 호출해 뷰를 만들거나, 객체가 다른 함수나 뷰 안에서 호출되는 경우 Snowflake는 객체 종속성을 기록하지 않아요. 예를 들어:
create or replace view v_on_stage_function
as
select *
from T1
where get_presigned_url(@stage1, 'data_0.csv.gz')
is not null;
이 예에서 get_presigned_url 함수는 stage1 스테이지를 호출해요. Snowflake는 v_on_stage_function이라는 뷰가 stage1이라는 스테이지에 종속된다고 기록하지 않아요.
- 깨진 종속성: 종속성 유형 값이
BY_NAME_AND_ID이고 객체에 대한 CREATE OR REPLACE 또는 ALTER 작업으로 인해 객체 종속성이 변경되면 Snowflake는 이러한 작업 이전의 객체 종속성만 기록해요. Snowflake는 이러한 작업 후에 뷰 쿼리 결과에 객체 종속성을 기록하지 않아요. 결과가 깨진 참조이기 때문이에요.
Snowflake 기능 및 서비스와의 객체 종속성
- 외부 객체: Snowflake는 Snowflake 객체에 대해서만 객체 종속성을 추적해요. 예를 들어 Snowflake 객체가 Amazon S3 버킷에 종속된다면, 버킷은 Snowflake 객체가 아닌 Amazon 객체이므로 이 뷰는 버킷에 대한 종속성을 기록하지 않아요.
- 복제: 2차 객체가 1차 객체에 종속되는 동안 이 뷰는 복제 작업으로 인한 종속성을 기록하지 않아요.
- 데이터 공유: 공급자 계정의 경우 이 뷰는 데이터 공유 공급자 계정이 데이터 공유 소비자 계정의 종속 객체를 결정할 수 있게 하지 않아요. 예를 들어 데이터 공유 공급자가 뷰를 만들어 공유한다고 가정하세요. 데이터 공유 공급자는 이 뷰를 사용해 공유 뷰에서 만들어진 소비자 계정의 객체(예: 새 테이블이나 뷰)를 결정할 수 없어요. 소비자 계정의 경우 이 뷰는 데이터 공유 소비자 계정이 데이터 공유 공급자 계정의 종속 객체를 결정할 수 있게 하지 않아요. 예를 들어 데이터 공유 소비자 계정이 데이터 공유 공급자 계정이 제공하는 UDF를 사용한다면, 데이터 공유 소비자는 이 뷰를 사용해 공유 UDF가 종속되는 객체를 식별할 수 없어요. 자세한 내용은 사용 메모를 참조하세요.
OBJECT_DEPENDENCIES 뷰 쿼리
다음 예제는 다음 사용 사례를 다뤄요:
- 외부 테이블에 종속되는 객체 표시.
- 영향 분석: 테이블이 참조하는 객체 찾기.
- GDPR: 주어진 뷰의 데이터 소스 찾기.
- 데이터 공유.
외부 테이블에 종속되는 객체 표시
sales_staging_table이라는 외부 테이블에서 sales_view라는 구체화된 뷰를 만들어요:
CREATE OR REPLACE MATERIALIZED VIEW sales_view AS SELECT * FROM sales_staging_table;
공유 SNOWFLAKE 데이터베이스의 Account Usage 스키마에서 OBJECT_DEPENDENCIES 뷰를 쿼리해요. 구체화된 뷰가 referencing_object_name이고 외부 테이블이 referenced_object_domain이라는 점에 유의하세요:
SELECT referencing_object_name, referencing_object_domain, referenced_object_name, referenced_object_domain
FROM snowflake.account_usage.object_dependencies
WHERE referenced_object_name = 'SALES_STAGING_TABLE' and referenced_object_domain = 'EXTERNAL TABLE';
| REFERENCING_OBJECT_NAME | REFERENCING_OBJECT_DOMAIN | REFERENCED_OBJECT_NAME | REFERENCED_OBJECT_DOMAIN |
|---|---|---|---|
| SALES_VIEW | MATERIALIZED VIEW | SALES_STAGING_TABLE | EXTERNAL TABLE |
영향 분석: 테이블이 참조하는 객체 찾기
NA가 북미, US가 미국, CAL이 캘리포니아를 나타내는 SALES_NA라는 기본 테이블과 일련의 중첩 뷰를 고려하세요:
- (테이블)
SALES_NA» (뷰)NORTH_AMERICA_SALES» (뷰)US_SALES - (테이블)
SALES_NA» (뷰)NORTH_AMERICA_SALES» (뷰)CAL_SALES
테이블과 중첩 뷰를 만들려면 다음 명령을 실행하세요:
CREATE TABLE sales_na(product string);
CREATE OR REPLACE VIEW north_america_sales AS SELECT * FROM sales_na;
CREATE VIEW us_sales AS SELECT * FROM north_america_sales;
CREATE VIEW cal_sales AS SELECT * FROM north_america_sales;
마찬가지로 기본 테이블 SALES_NA와 중첩 뷰의 관계, 그리고 UK가 영국을 나타내는 기본 테이블 SALES_UK와 중첩 뷰의 관계를 고려하세요. GLOBAL_SALES라는 뷰를 파생하는 데 두 개의 서로 다른 뷰가 소스 객체로 작동한다는 점에 유의하세요:
- (테이블)
SALES_NA» (뷰)NORTH_AMERICA_SALES» (뷰)GLOBAL_SALES - (테이블)
SALES_UK» (뷰)GLOBAL_SALES
이 중첩 뷰들을 만들려면 다음 명령을 실행하세요:
CREATE TABLE sales_uk (product string);
CREATE VIEW global_sales AS SELECT * FROM sales_uk UNION ALL SELECT * FROM north_america_sales;
테이블 SALES_NA의 객체 참조를 확인하려면 공유 SNOWFLAKE 데이터베이스의 Account Usage 스키마에서 OBJECT_DEPENDENCIES 뷰를 쿼리하세요. 쿼리 결과의 네 번째 행은 테이블 SALES_NA를 지정하지만 테이블 SALES_UK를 참조하지 않는다는 점에 유의하세요:
WITH RECURSIVE referenced_cte
(object_name_path, referenced_object_name, referenced_object_domain, referencing_object_domain, referencing_object_name, referenced_object_id, referencing_object_id)
AS
(
SELECT referenced_object_name || '-->' || referencing_object_name as object_name_path,
referenced_object_name, referenced_object_domain, referencing_object_domain, referencing_object_name, referenced_object_id, referencing_object_id
FROM snowflake.account_usage.object_dependencies referencing
WHERE true
AND referenced_object_name = 'SALES_NA' AND referenced_object_domain='TABLE'
UNION ALL
SELECT object_name_path || '-->' || referencing.referencing_object_name,
referencing.referenced_object_name, referencing.referenced_object_domain, referencing.referencing_object_domain, referencing.referencing_object_name,
referencing.referenced_object_id, referencing.referencing_object_id
FROM snowflake.account_usage.object_dependencies referencing JOIN referenced_cte
ON referencing.referenced_object_id = referenced_cte.referencing_object_id
AND referencing.referenced_object_domain = referenced_cte.referencing_object_domain
)
SELECT object_name_path, referenced_object_name, referenced_object_domain, referencing_object_name, referencing_object_domain
FROM referenced_cte
;
| OBJECT_NAME_PATH | REFERENCED_OBJECT_NAME | REFERENCED_OBJECT_DOMAIN | REFERENCING_OBJECT_NAME | REFERENCING_OBJECT_DOMAIN |
|---|---|---|---|---|
| SALES_NA-->NORTH_AMERICA_SALES | SALES_NA | TABLE | NORTH_AMERICA_SALES | VIEW |
| SALES_NA-->NORTH_AMERICA_SALES-->CAL_SALES | NORTH_AMERICA_SALES | VIEW | CAL_SALES | VIEW |
| SALES_NA-->NORTH_AMERICA_SALES-->US_SALES | NORTH_AMERICA_SALES | VIEW | US_SALES | VIEW |
| SALES_NA-->NORTH_AMERICA_SALES-->GLOBAL_SALES | NORTH_AMERICA_SALES | VIEW | GLOBAL_SALES | VIEW |
GDPR: 주어진 뷰의 데이터 소스 찾기
파생 객체(예: 뷰, CTAS)는 맞춤형 뷰나 대시보드를 제공하기 위해 여러 다른 소스 객체에서 만들 수 있어요. GDPR 같은 규제 요구 사항을 충족하기 위해 규정 준수 담당자와 감사자는 주어진 객체에서 원래 데이터 소스까지 데이터를 추적할 수 있어야 해요.
예를 들어 뷰 GLOBAL_SALES는 서로 다른 두 기본 테이블을 가리키는 두 개의 서로 다른 종속성 경로에서 파생돼요:
- (테이블)
SALES_NA» (뷰)NORTH_AMERICA_SALES» (뷰)GLOBAL_SALES - (테이블)
SALES_UK» (뷰)GLOBAL_SALES
이 중첩 뷰들을 만들려면 다음 명령을 실행하세요:
CREATE TABLE sales_na (product string);
CREATE OR REPLACE VIEW north_america_sales AS SELECT * FROM sales_na;
CREATE TABLE sales_uk (product string);
CREATE VIEW global_sales AS SELECT * FROM sales_uk UNION ALL SELECT * FROM north_america_sales;
뷰 GLOBAL_SALES의 데이터 소스를 찾으려면 공유 SNOWFLAKE 데이터베이스의 Account Usage 스키마에서 OBJECT_DEPENDENCIES 뷰를 쿼리하세요. 쿼리 결과의 각 행은 고유한 객체에 대한 종속성 경로를 지정해요.
WITH RECURSIVE referenced_cte
(object_name_path, referenced_object_name, referenced_object_domain, referencing_object_domain, referencing_object_name, referenced_object_id, referencing_object_id)
AS
(
SELECT referenced_object_name || '<--' || referencing_object_name AS object_name_path,
referenced_object_name, referenced_object_domain, referencing_object_domain, referencing_object_name, referenced_object_id, referencing_object_id
from snowflake.account_usage.object_dependencies referencing
WHERE true
AND referencing_object_name = 'GLOBAL_SALES' and referencing_object_domain='VIEW'
UNION ALL
SELECT referencing.referenced_object_name || '<--' || object_name_path,
referencing.referenced_object_name, referencing.referenced_object_domain, referencing.referencing_object_domain, referencing.referencing_object_name,
referencing.referenced_object_id, referencing.referencing_object_id
FROM snowflake.account_usage.object_dependencies referencing JOIN referenced_cte
ON referencing.referencing_object_id = referenced_cte.referenced_object_id
AND referencing.referencing_object_domain = referenced_cte.referenced_object_domain
)
SELECT object_name_path, referencing_object_name, referencing_object_domain, referenced_object_name, referenced_object_domain
FROM referenced_cte
;
| OBJECT_NAME_PATH | REFERENCING_OBJECT_NAME | REFERENCING_OBJECT_DOMAIN | REFERENCED_OBJECT_NAME | REFERENCED_OBJECT_DOMAIN |
|---|---|---|---|---|
| SALES_UK<--GLOBAL_SALES | GLOBAL_SALES | VIEW | SALES_UK | TABLE |
| NORTH_AMERICA_SALES<--GLOBAL_SALES | GLOBAL_SALES | VIEW | NORTH_AMERICA_SALES | VIEW |
| SALES_NA<--NORTH_AMERICA_SALES<--GLOBAL_SALES | NORTH_AMERICA_SALES | VIEW | SALES_NA | TABLE |
데이터 공유
소비자 계정의 OBJECT_DEPENDENCIES 뷰에서 가져온 다음 표를 고려하세요. 여기서:
V1은 소비자가 공유 객체에서 만든 뷰를 지정해요.S_V1은 공급자가 공유하는 뷰를 지정해요.S_T1은 공급자가 공유하는 테이블을 지정해요.
| 행 | REFERENCING_OBJECT_NAME | REFERENCED_OBJECT_NAME | REFERENCED_OBJECT_DOMAIN | REFERENCED_OBJECT_ID |
|---|---|---|---|---|
| 1 | V1 | S_V1 | TABLE | NULL |
| 2 | V1 | S_T1 | TABLE | NULL |
이 표를 고려하면 다음에 유의하세요:
- 공급자가 공유에서
S_T1을 철회하면,S_T1이 철회 전에 이름이 바뀌지 않은 한 소비자는 로컬 뷰에서S_T1(행 2)을 지정하는 행을 계속 볼 수 있어요. - 공급자가 계정에서 테이블이나 뷰를 삭제하면 해당 테이블이나 뷰는 더 이상 공유에 포함되지 않아요. 로컬 소비자 뷰는 공급자 계정의 삭제 작업 이전에 테이블이나 뷰가 공유됐으므로 삭제된 테이블이나 뷰에 대한 기존 레코드를 보존해요.
소비자는 공급자 계정의 뷰 변경을 관찰할 수 없어요.