Delta Lake에서 생성된 열
Important
이 기능은 공개 미리 보기 상태입니다.
Delta Lake는 델타 테이블의 다른 열에 대해 사용자 지정 함수를 기반으로 하여 값이 자동으로 생성되는 특수한 유형의 열인 생성된 열을 지원합니다. 생성된 열이 있는 테이블에 쓰고 해당 열에 대한 값을 명시적으로 제공하지 않으면 Delta Lake에서 자동으로 값을 계산합니다. 예를 들어 타임스탬프 열에서 날짜 열을 자동으로 생성할 수 있습니다(테이블을 날짜별로 분할하기 위한 경우). 테이블에 대한 모든 쓰기는 타임스탬프 열에 대한 데이터만 지정하면 됩니다. 그러나 값을 명시적으로 제공하는 경우 값은 제약 조건 (<value> <=> <generation expression>) IS TRUE
을(를) 충족해야 하며, 그렇지 않으면 오류로 인해 쓰기가 실패합니다.
Important
생성된 열로 만든 테이블에는 기본값보다 높은 테이블 작성기 프로토콜 버전이 있습니다. 테이블 프로토콜 버전 관리를 이해하려면 Azure Databricks가 Delta Lake 기능 호환성을 어떻게 관리하나요?를 참조하고, 더 높은 버전의 테이블 프로토콜 버전을 갖는 것이 무엇을 의미하는지 알아보세요.
생성된 열이 있는 테이블 만들기
다음 예제에서는 생성된 열이 있는 테이블을 만드는 방법을 보여 줍니다.
SQL
CREATE TABLE default.people10m (
id INT,
firstName STRING,
middleName STRING,
lastName STRING,
gender STRING,
birthDate TIMESTAMP,
dateOfBirth DATE GENERATED ALWAYS AS (CAST(birthDate AS DATE)),
ssn STRING,
salary INT
)
Python
DeltaTable.create(spark) \
.tableName("default.people10m") \
.addColumn("id", "INT") \
.addColumn("firstName", "STRING") \
.addColumn("middleName", "STRING") \
.addColumn("lastName", "STRING", comment = "surname") \
.addColumn("gender", "STRING") \
.addColumn("birthDate", "TIMESTAMP") \
.addColumn("dateOfBirth", DateType(), generatedAlwaysAs="CAST(birthDate AS DATE)") \
.addColumn("ssn", "STRING") \
.addColumn("salary", "INT") \
.execute()
Scala
DeltaTable.create(spark)
.tableName("default.people10m")
.addColumn("id", "INT")
.addColumn("firstName", "STRING")
.addColumn("middleName", "STRING")
.addColumn(
DeltaTable.columnBuilder("lastName")
.dataType("STRING")
.comment("surname")
.build())
.addColumn("lastName", "STRING", comment = "surname")
.addColumn("gender", "STRING")
.addColumn("birthDate", "TIMESTAMP")
.addColumn(
DeltaTable.columnBuilder("dateOfBirth")
.dataType(DateType)
.generatedAlwaysAs("CAST(dateOfBirth AS DATE)")
.build())
.addColumn("ssn", "STRING")
.addColumn("salary", "INT")
.execute()
생성된 열은 일반 열인 것처럼 저장됩니다. 즉, 스토리지 공간을 차지합니다.
생성된 열에 적용되는 제한 사항은 다음과 같습니다.
- 생성 식은 다음 유형의 함수를 제외하고 동일한 인수 값이 지정되면 항상 동일한 결과를 반환하는 Spark의 모든 SQL 함수를 사용할 수 있습니다.
- 사용자 정의 함수
- 집계 함수.
- 창 함수
- 여러 행을 반환하는 함수
Delta Lake는 다음 식 중 하나로 파티션 열을 정의할 때마다 쿼리에 대한 파티션 필터를 생성할 수 있습니다.
참고 항목
Photon은 Databricks Runtime 10.4 LTS 이하에서 필요합니다. Databricks Runtime 11.3 LTS 이상에서는 Photon이 필요하지 않습니다.
CAST(col AS DATE)
및col
의 형식은TIMESTAMP
입니다.YEAR(col)
및col
의 형식은TIMESTAMP
입니다.YEAR(col), MONTH(col)
에 의해 정의된 2개의 파티션 열과col
형식은TIMESTAMP
입니다.YEAR(col), MONTH(col), DAY(col)
에 의해 정의된 3개의 파티션 열과col
형식은TIMESTAMP
입니다.YEAR(col), MONTH(col), DAY(col), HOUR(col)
에 의해 정의된 4개의 파티션 열과col
형식은TIMESTAMP
입니다.SUBSTRING(col, pos, len)
및col
형식은STRING
입니다.DATE_FORMAT(col, format)
및col
의 형식은TIMESTAMP
입니다.yyyy-MM
및yyyy-MM-dd-HH
같은 패턴으로 날짜 형식만 사용할 수 있습니다.- Databricks Runtime 10.4 LTS 이상에서는
yyyy-MM-dd
패턴을 사용할 수도 있습니다.
파티션 열이 앞의 식 중 하나에 의해 정의되고 쿼리가 생성 식의 기본 열을 사용하여 데이터를 필터링하는 경우 Delta Lake는 기본 열과 생성된 열 간의 관계를 확인하고 가능한 경우 생성된 파티션 열에 따라 파티션 필터를 채웁니다. 예를 들어 다음 테이블이 제공됩니다.
CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
eventDate date GENERATED ALWAYS AS (CAST(eventTime AS DATE))
)
PARTITIONED BY (eventType, eventDate)
다음 쿼리를 실행하는 경우:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake는 파티션 필터를 지정하지 않은 경우에도 이전 쿼리가 date=2020-10-01
파티션의 데이터만 읽도록 파티션 필터를 자동으로 생성합니다.
또 다른 예로, 다음 표가 제공됩니다.
CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
year INT GENERATED ALWAYS AS (YEAR(eventTime)),
month INT GENERATED ALWAYS AS (MONTH(eventTime)),
day INT GENERATED ALWAYS AS (DAY(eventTime))
)
PARTITIONED BY (eventType, year, month, day)
다음 쿼리를 실행하는 경우:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake는 파티션 필터를 지정하지 않은 경우에도 이전 쿼리가 year=2020/month=10/day=01
파티션의 데이터만 읽도록 파티션 필터를 자동으로 생성합니다.
EXPLAIN 절을 사용하고 제공된 계획을 확인하여 Delta Lake가 파티션 필터를 자동으로 생성하는지 여부를 확인할 수 있습니다.
Delta Lake에서 ID 열 사용
Important
Delta 테이블에서 ID 열을 선언하면 동시 트랜잭션이 비활성화됩니다. 대상 테이블에 대한 동시 쓰기가 필요하지 않은 경우 ID 열만 사용합니다.
Delta Lake ID 열은 테이블에 삽입된 각 레코드에 고유한 값을 할당하는 생성된 열의 형식입니다. 다음 예제에서는 create table 문 중에 ID 열을 선언하기 위한 기본 구문을 보여줍니다.
SQL
CREATE TABLE table_name (
id_col1 BIGINT GENERATED ALWAYS AS IDENTITY,
id_col2 BIGINT GENERATED ALWAYS AS IDENTITY (START WITH -1 INCREMENT BY 1),
id_col3 BIGINT GENERATED BY DEFAULT AS IDENTITY,
id_col4 BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH -1 INCREMENT BY 1)
)
Python
from delta.tables import DeltaTable, IdentityGenerator
from pyspark.sql.types import LongType
DeltaTable.create()
.tableName("table_name")
.addColumn("id_col1", dataType=LongType(), generatedAlwaysAs=IdentityGenerator())
.addColumn("id_col2", dataType=LongType(), generatedAlwaysAs=IdentityGenerator(start=-1, step=1))
.addColumn("id_col3", dataType=LongType(), generatedByDefaultAs=IdentityGenerator())
.addColumn("id_col4", dataType=LongType(), generatedByDefaultAs=IdentityGenerator(start=-1, step=1))
.execute()
Scala
import io.delta.tables.DeltaTable
import org.apache.spark.sql.types.LongType
DeltaTable.create(spark)
.tableName("table_name")
.addColumn(
DeltaTable.columnBuilder(spark, "id_col1")
.dataType(LongType)
.generatedAlwaysAsIdentity().build())
.addColumn(
DeltaTable.columnBuilder(spark, "id_col2")
.dataType(LongType)
.generatedAlwaysAsIdentity(start = -1L, step = 1L).build())
.addColumn(
DeltaTable.columnBuilder(spark, "id_col3")
.dataType(LongType)
.generatedByDefaultAsIdentity().build())
.addColumn(
DeltaTable.columnBuilder(spark, "id_col4")
.dataType(LongType)
.generatedByDefaultAsIdentity(start = -1L, step = 1L).build())
.execute()
참고 항목
ID 열에 대한 Scala 및 Python API는 Databricks Runtime 16.0 이상에서 사용할 수 있습니다.
ID 열이 있는 테이블을 만들기 위한 모든 SQL 구문 옵션을 보려면 CREATE TABLE [USING]을 참조하세요.
선택적으로 다음을 지정할 수 있습니다.
- 시작 값
- 양수 또는 음수일 수 있는 단계적 크기입니다.
시작 값과 단계 크기 모두 기본값은 .입니다 1
. 의 단계 크기를 0
지정할 수 없습니다.
ID 열에 의해 할당된 값은 지정된 단계의 방향과 지정된 단계 크기의 배수로 고유하고 증가하지만 연속되지는 않습니다. 예를 들어 시작 값 0
와(과) 단계 크기 2
이(가) 모두 양수이더라도 일부 짝수는 건너뛸 수 있습니다.
GENERATED BY DEFAULT AS IDENTITY
절을 사용할 때 삽입 작업은 ID 열에 대한 값을 지정할 수 있습니다. 수동으로 값을 설정하는 기능을 재정의하도록 절을 GENERATED ALWAYS AS IDENTITY
(으)로 수정합니다.
ID 열은 BIGINT
형식만 지원하며 할당된 값이 지원되는 BIGINT
범위를 초과하면 작업이 실패합니다.
ID 열 값을 데이터 와 동기화하는 방법에 대한 자세한 내용은 ALTER TABLE ... COLUMN 절입니다.
CTAS 및 ID 열
CREATE TABLE table_name AS SELECT
(CTAS) 문을 사용하는 경우 스키마, ID 열 제약 조건 또는 다른 테이블 사양을 정의할 수 없습니다.
ID 열이 있는 새 테이블을 만들고 기존 데이터로 채려면 다음을 수행합니다.
- ID 열 정의 및 기타 테이블 속성을 포함하여 올바른 스키마를 사용하여 테이블을 만듭니다.
INSERT
작업 실행
다음 예제에서는 DEFAULT
키워드를 사용하여 ID 열을 정의합니다. 테이블에 삽입된 데이터에 ID 열에 대한 유효한 값이 포함된 경우 이러한 값이 사용됩니다.
CREATE OR REPLACE TABLE new_table (
id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 5),
event_date DATE,
some_value BIGINT
);
-- Inserts records including existing IDs
INSERT INTO new_table
SELECT id, event_date, some_value FROM old_table;
-- Insert records and generate new IDs
INSERT INTO new_table
SELECT event_date, some_value FROM new_records;
ID 열 제한 사항
ID 열을 사용하는 경우 다음과 같은 제한 사항이 있습니다.
- ID 열이 활성화된 테이블에서는 동시 트랜잭션이 지원되지 않습니다.
- ID 열별로 테이블을 분할할 수 없습니다.
ALTER TABLE
을(를)ADD
,REPLACE
, 또는CHANGE
ID 열에 사용할 수 없습니다.- 기존 레코드의 ID 열 값을 업데이트할 수 없습니다.
참고 항목
기존 레코드의 IDENTITY
값을 변경하려면 레코드와 INSERT
을(를) 새 레코드로 삭제해야 합니다.