수동 파티셔닝
수동 파티셔닝은 사용자가 테이블을 생성할 때 파티션 규칙을 명시적으로 지정하는 파티셔닝 방식입니다. 이 문서에서는 Range 파티셔닝, List 파티셔닝, NULL 파티셔닝의 구문, 사용 사례, 권장 사항을 포함하여 Doris에서 수동 파티셔닝을 사용하는 방법을 설명합니다.
파티션 컬럼 규칙
수동 파티셔닝을 사용하기 전에 파티션 컬럼에 대한 일반적인 규칙을 이해해야 합니다.
- 파티션 컬럼은 하나 이상의 컬럼으로 구성할 수 있으며, 반드시 KEY 컬럼이어야 합니다.
- 파티션 컬럼의 자료형에 관계없이 파티션 값은 큰따옴표로 감싸서 작성해야 합니다.
- 파티션 개수에는 이론적인 상한이 없습니다. 다만 기본적으로 테이블당 4096개의 파티션으로 제한됩니다. 이 한도를 초과하려면 FE의
max_multi_partition_num및max_dynamic_partition_num설정을 수정하세요. - 파티셔닝 없이 테이블을 생성하면 시스템이 테이블과 같은 이름으로 전체 값 범위를 포함하는 단일 파티션을 자동으로 생성합니다. 이 파티션은 사용자에게 표시되지 않으며 수정하거나 삭제할 수 없습니다.
- 범위가 서로 겹치는 파티션은 생성할 수 없습니다.
Range 파티셔닝
Range 파티셔닝은 파티션 컬럼의 값 범위에 따라 데이터를 서로 다른 파티션으로 나눕니다. 파티션 컬럼에는 일반적으로 시간 컬럼을 사용하므로 오래된 데이터와 새로운 데이터를 쉽게 관리할 수 있습니다.
지원되는 컬럼 자료형: DATE, DATETIME, TIMESTAMPTZ, TINYINT, SMALLINT, INT, BIGINT, LARGEINT.
Range 파티셔닝은 사용 상황에 맞게 다음 네 가지 형식을 지원합니다.
| 형식 | 사용 사례 |
|---|---|
| FIXED RANGE | 각 파티션의 상한과 하한을 정밀하게 제어해야 하는 경우 |
| LESS THAN | 파티션의 상한만 고려하고 시간순으로 파티션을 추가하는 경우 |
| BATCH RANGE | 동일한 간격으로 숫자 또는 시간 파티션을 일괄 생성하는 경우 |
| MULTI RANGE | 시간 범위마다 서로 다른 간격으로 파티션을 일괄 생성하는 경우 |
1. FIXED RANGE
파티션의 하한은 포함하고 상한은 포함하지 않는 구간을 정의합니다.
구문:
PARTITION BY RANGE(col1[, col2, ...])
(
PARTITION partition_name1 VALUES [("k1-lower1", "k2-lower1", "k3-lower1",...), ("k1-upper1", "k2-upper1", "k3-upper1", ...)),
PARTITION partition_name2 VALUES [("k1-lower1-2", "k2-lower1-2", ...), ("k1-upper1-2", MAXVALUE, ))
)
예제:
PARTITION BY RANGE(`date`)
(
PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")),
PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")),
PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01"))
)
2. LESS THAN
파티션의 상한만 정의하며, 하한은 이전 파티션의 상한에 따라 결정됩니다.
구문:
PARTITION BY RANGE(col1[, col2, ...])
(
PARTITION partition_name1 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...),
PARTITION partition_name2 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...)
)
예제:
PARTITION BY RANGE(`date`)
(
PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
PARTITION `p201703` VALUES LESS THAN ("2017-04-01"),
PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")),
PARTITION `other` VALUES LESS THAN (MAXVALUE)
)
3. BATCH RANGE
숫자형 및 시간형 RANGE 파티션을 일괄 생성합니다. 지정된 간격에 따라 각 파티션의 하한은 포함하고 상한은 포함하지 않는 구간을 정의합니다.
구문:
PARTITION BY RANGE(int_col)
(
FROM (start_num) TO (end_num) INTERVAL interval_value
)
PARTITION BY RANGE(date_col)
(
FROM ("start_date") TO ("end_date") INTERVAL num YEAR | num MONTH | num WEEK | num DAY | 1 HOUR
)
예제:
PARTITION BY RANGE(age)
(
FROM (1) TO (100) INTERVAL 10
)
PARTITION BY RANGE(`date`)
(
FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 2 YEAR
)
4. MULTI RANGE
하한은 포함하고 상한은 포함하지 않는 구간의 RANGE 파티션을 일괄 생성하며, 동일한 구문 내에서 서로 다른 간격을 지정할 수 있습니다.
예제:
PARTITION BY RANGE(col)
(
FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 1 YEAR,
FROM ("2021-11-14") TO ("2022-11-14") INTERVAL 1 MONTH,
FROM ("2022-11-14") TO ("2023-01-03") INTERVAL 1 WEEK,
FROM ("2023-01-03") TO ("2023-01-14") INTERVAL 1 DAY,
PARTITION p_20230114 VALUES [('2023-01-14'), ('2023-01-15'))
)
List 파티셔닝
List 파티셔닝은 파티션 컬럼에 대해 열거된 값을 기준으로 데이터를 서로 다른 파티션으로 나눕니다. 행의 값이 해당 파티션에 정의된 열거 값 중 하나와 일치하는 경우에만 그 파티션으로 라우팅됩니다.
지원되는 컬럼 자료형: BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE, DATETIME, TIMESTAMPTZ, CHAR, VARCHAR.
구문 키워드: VALUES IN (...)을 사용하여 각 파티션에 포함되는 열거 값을 지정합니다.
단일 컬럼 List 파티셔닝
PARTITION BY LIST(city)
(
PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"),
PARTITION `p_usa` VALUES IN ("New York", "San Francisco"),
PARTITION `p_jp` VALUES IN ("Tokyo")
)
다중 컬럼 List 파티셔닝
PARTITION BY LIST(id, city)
(
PARTITION p1_city VALUES IN (("1", "Beijing"), ("1", "Shanghai")),
PARTITION p2_city VALUES IN (("2", "Beijing"), ("2", "Shanghai")),
PARTITION p3_city VALUES IN (("3", "Beijing"), ("3", "Shanghai"))
)
NULL 파티셔닝
기본적으로 파티션 컬럼은 NOT NULL이어야 합니다. NULL을 허용하는 컬럼을 파티션 컬럼으로 사용하려면 다음 세션 변수를 설정하세요.
SET allow_partition_column_nullable = true;
파티션 유형별 NULL 값 처리 방식은 다음과 같습니다.
| 파티션 유형 | NULL 값 처리 방식 |
|---|---|
| LIST 파티션 | 실제 NULL 파티션을 지원함 |
| RANGE 파티션(LESS THAN 사용) | NULL 값이 가장 작은 LESS THAN 파티션에 저장됨 |
| RANGE 파티션(LESS THAN 미사용) | NULL 값을 삽입할 수 없음 |
시나리오 1: LIST 파티션에서 NULL 지원
mysql> create table null_list(
-> k0 varchar null
-> )
-> partition by list (k0)
-> (
-> PARTITION pX values in ((NULL))
-> )
-> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
-> properties("replication_num" = "1");
Query OK, 0 rows affected (0.11 sec)
mysql> insert into null_list values (null);
Query OK, 1 row affected (0.19 sec)
mysql> select * from null_list;
+------+
| k0 |
+------+
| NULL |
+------+
1 row in set (0.18 sec)
시나리오 2: RANGE 파티션에서 NULL을 가장 작은 LESS THAN 파티션으로 라우팅
mysql> create table null_range(
-> k0 int null
-> )
-> partition by range (k0)
-> (
-> PARTITION p10 values less than (10),
-> PARTITION p100 values less than (100),
-> PARTITION pMAX values less than (maxvalue)
-> )
-> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
-> properties("replication_num" = "1");
Query OK, 0 rows affected (0.12 sec)
mysql> insert into null_range values (null);
Query OK, 1 row affected (0.19 sec)
mysql> select * from null_range partition(p10);
+------+
| k0 |
+------+
| NULL |
+------+
1 row in set (0.18 sec)
시나리오 3: LESS THAN을 사용하지 않는 RANGE 파티션은 NULL을 허용하지 않음
mysql> create table null_range2(
-> k0 int null
-> )
-> partition by range (k0)
-> (
-> PARTITION p200 values [("100"), ("200"))
-> )
-> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
-> properties("replication_num" = "1");
Query OK, 0 rows affected (0.13 sec)
mysql> insert into null_range2 values (null);
ERROR 5025 (HY000): Insert has filtered data in strict mode, tracking_url=......