테이블 스키마 진화¶
반정형 데이터는 시간이 지남에 따라 진화하는 경향이 있습니다. 데이터를 생성하는 시스템은 추가 정보를 수용하려고 새 열을 추가하므로 다운스트림 테이블이 그에 따라 진화해야 합니다.
Snowflake의 테이블 구조는 데이터 원본에서 받은 새 데이터의 구조를 지원하도록 자동으로 진화할 수 있습니다. Snowflake는 다음을 지원합니다.
자동으로 새 열 추가.
새 데이터 파일에서 누락된 열에서 NOT NULL 제약 조건 자동 삭제.
테이블 스키마 진화를 활성화하려면 다음을 수행하십시오.
새 테이블을 생성하는 경우 CREATE TABLE 명령을 사용할 때
ENABLE_SCHEMA_EVOLUTION
매개 변수를 TRUE로 설정합니다.기존 테이블의 경우 ALTER TABLE 명령을 사용하여 테이블을 수정하고
ENABLE_SCHEMA_EVOLUTION
매개 변수를 TRUE로 설정합니다.
파일에서 데이터를 로드하면 다음이 모두 true일 때 테이블 열이 진화합니다.
COPY INTO <테이블> 문은
MATCH_BY_COLUMN_NAME
옵션을 포함합니다.데이터를 로드하는 데 사용되는 역할에는 테이블에 대한 EVOLVE SCHEMA 또는 OWNERSHIP 권한이 있습니다.
또한 CSV를 사용한 스키마 진화의 경우 MATCH_BY_COLUMN_NAME
및 PARSE_HEADER
와 함께 사용할 때 ERROR_ON_COLUMN_COUNT_MISMATCH
를 false로 설정해야 합니다.
스키마 진화는 독립형 기능이지만 클라우드 저장소의 파일 세트에서 열 정의 검색 지원 과 함께 사용할 수 있습니다. 이러한 기능을 함께 사용하면 지속적인 데이터 파이프라인이 클라우드 저장소의 데이터 파일 세트에서 새 테이블을 생성한 다음 열 추가 또는 삭제로 새 원본 데이터 파일의 스키마가 진화함에 따라 테이블의 열을 수정할 수 있습니다.
사용법 노트¶
이 기능은 Apache Avro, Apache Parquet, CSV, JSON 및 ORC 파일을 지원합니다.
이 기능은 COPY INTO <테이블> 문과 Snowpipe 데이터 로드로 제한됩니다. INSERT 작업은 대상 테이블 스키마를 자동으로 발전시킬 수 없습니다.
Snowflake Ingest SDK를 직접 사용하는 Snowpipe Streaming 데이터 로드는 스키마 진화에서 지원되지 않습니다. Snowpipe Streaming을 사용하는 Kafka 커넥터 는 스키마 감지 및 진화를 지원합니다.
기본적으로, 이 기능은 최대 10개의 열을 추가하거나 COPY 작업당 1개 이하의 스키마를 발전시키는 것으로 제한됩니다. COPY 작업당 10개 이상의 추가된 열 또는 1개 이상의 스키마를 요청하려면 Snowflake 지원팀 에 문의하십시오.
NOT NULL 열 제약 조건 삭제에는 제한이 없습니다.
스키마 진화는 INFORMATION_SCHEMA COLUMNS 뷰, ACCOUNT_USAGE COLUMNS 뷰, DESCRIBE TABLE 명령, SHOW COLUMNS 명령 과 같은 뷰와 명령에서
SchemaEvolutionRecord
출력으로 추적됩니다.
예¶
다음 예제에서는 Parquet 데이터 세트에서 파생된 열 정의가 있는 테이블을 만듭니다. 테이블에 대해 자동 테이블 스키마 진화가 활성화되면 추가 이름/값 쌍이 있는 Parquet 파일에서 추가 데이터 로드를 통해 자동으로 테이블에 열이 추가됩니다.
문에서 참조하는 mystage
스테이지와 my_parquet_format
파일 형식이 이미 있어야 합니다. 스테이지 정의에서 참조하는 클라우드 저장소 위치에 파일 세트가 이미 스테이징되어 있어야 합니다.
이 예는 INFER_SCHEMA 항목의 예를 기반으로 합니다.
-- Create table t1 in schema d1.s1, with the column definitions derived from the staged file1.parquet file. USE SCHEMA d1.s1; CREATE OR REPLACE TABLE t1 USING TEMPLATE ( SELECT ARRAY_AGG(object_construct(*)) FROM TABLE( INFER_SCHEMA( LOCATION=>'@mystage/file1.parquet', FILE_FORMAT=>'my_parquet_format' ) )); -- Row data in file1.parquet. +------+------+------+ | COL1 | COL2 | COL3 | |------+------+------| | a | b | c | +------+------+------+ -- Describe the table. -- Note that column c2 is required in the Parquet file metadata. Therefore, the NOT NULL constraint is set for the column. DESCRIBE TABLE t1; +------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+ | name | type | kind | null? | default | primary key | unique key | check | expression | comment | policy name | |------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------| | COL1 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | | COL2 | VARCHAR(16777216) | COLUMN | N | NULL | N | N | NULL | NULL | NULL | NULL | | COL3 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | +------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+ -- Use the SECURITYADMIN role or another role that has the global MANAGE GRANTS privilege. -- Grant the EVOLVE SCHEMA privilege to any other roles that could insert data and evolve table schema in addition to the table owner. GRANT EVOLVE SCHEMA ON TABLE d1.s1.t1 TO ROLE r1; -- Enable schema evolution on the table. -- Note that the ENABLE_SCHEMA_EVOLUTION property can also be set at table creation with CREATE OR REPLACE TABLE ALTER TABLE t1 SET ENABLE_SCHEMA_EVOLUTION = TRUE; -- Load a new set of data into the table. -- The new data drops the NOT NULL constraint on the col2 column. -- The new data adds the new column col4. COPY INTO t1 FROM @mystage/file2.parquet FILE_FORMAT = (type=parquet) MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE; -- Row data in file2.parquet. +------+------+------+ | col1 | COL3 | COL4 | |------+------+------| | d | e | f | +------+------+------+ -- Describe the table. DESCRIBE TABLE t1; +------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+ | name | type | kind | null? | default | primary key | unique key | check | expression | comment | policy name | |------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------| | COL1 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | | COL2 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | | COL3 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | | COL4 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | +------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+ -- Note that since MATCH_BY_COLUMN_NAME is set as CASE_INSENSITIVE, all column names are retrieved as uppercase letters.