首批通过分布式安全可靠测评,为关键业务系统打造
设置分区策略
更新时间:2026-04-13 15:30:52
本文档旨在介绍分区创建策略和分区删除策略。
分区创建策略
注意
- 表如果属于表组(tablegroup),创建分区可能会失败或破坏负载均衡,请谨慎配置创建策略。
- 新建索引可能会导致表组(tablegroup)失效,因为同属于一个表组的表必须拥有完全一致的分区,而新建分区可能会破坏这种现状,导致表组失效。
自定义分区创建策略
自定义分区创建策略是通过 SQL 表达式来生成分区的上界,分为以下 3 个步骤:
通过 SQL 表达式获取基准时间:基准时间是指分区生成时所依赖的起始时间。
说明
以分区计划运行的时间为起始时间:直接使用
now()或者sysdate。定义分区生成的间隔:分区计划将会以此间隔作为分区生成的时间步长以生成若干个分区。您在 间隔 输入框中输入所需间隔后,ODC 通过
${INTERVAL}表达式引用该间隔,并且将该间隔加入到步骤 1 所生成的 SQL 表达式中。生成对应分区键类型的分区表达式:将步骤 1 和步骤 2 生成的时间类型的 SQL 表达式转换成对应分区键真实的类型(如果对应分区键的类型与 SQL 表达式的类型相同,可忽略此步骤)。
自定义分区创建策略中支持变量引用,目前支持的表达式如下:
| 表达式名 | 说明 | 示例 |
|---|---|---|
| INTERVAL | 时间间隔,用以描述分区生成时的步长。ODC 在运行时会将该变量引用替换为 创建规则 > 细则 > 间隔 中的内容。 | ${INTERVAL} |
通常情况下,如果您采用 自定义 方式创建分区策略表示需要将非时间类型分区键按照时间类型的方式递增生成新的分区。下表可以帮助您快速写出正确的 SQL 表达式:
分区上界生成表达式速查表 - MySQL 模式
| 分区表达式样例 | 说明 | 间隔 | 分区上界计算 SQL 表达式 |
... values less than ('2024') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y''') |
... values less than ('202401') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y01''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y%m''') |
|
... values less than ('2024-01') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y-01''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y-%m''') |
|
... values less than ('2024/01') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y/01''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y/%m''') |
|
... values less than ('20240101') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y0101''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y%m01''') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '''%Y%m%d''') |
|
... values less than ('2024-01-01') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y-01-01''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y-%m-01''') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '''%Y-%m-%d''') |
|
... values less than ('2024/01/01') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y/01/01''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y/%m/01''') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '''%Y/%m/%d''') |
|
... values less than ('2024-01-01 00:00:00') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y-01-01 00:00:00''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y-%m-01 00:00:00''') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '''%Y-%m-%d 00:00:00''') |
|
... values less than ('2024/01/01 00:00:00') |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '''%Y/01/01 00:00:00''') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '''%Y/%m/01 00:00:00''') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '''%Y/%m/%d 00:00:00''') |
|
... values less than (2024) |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '%Y') |
... values less than (202401) |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '%Y01') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '%Y%m') |
|
... values less than (20240101) |
按年生成 | 1 | date_format(now() + interval ${INTERVAL} year, '%Y0101') |
| 按月生成 | 1 | date_format(now() + interval ${INTERVAL} month, '%Y%m01') |
|
| 按日生成 | 1 | date_format(now() + interval ${INTERVAL} day, '%Y%m%d') |
|
... values less than (1709222400)注:Unix 时间戳 |
按年生成 | 1 | unix_timestamp(str_to_date(date_format(now() + interval ${INTERVAL} year, '%Y-01-01 00:00:00'), '%Y-%m-%d %H:%i:%s')) |
| 按月生成 | 1 | unix_timestamp(str_to_date(date_format(now() + interval ${INTERVAL} month, '%Y-%m-01 00:00:00'), '%Y-%m-%d %H:%i:%s')) |
|
| 按日生成 | 1 | unix_timestamp(str_to_date(date_format(now() + interval ${INTERVAL} day, '%Y-%m-%d 00:00:00'), '%Y-%m-%d %H:%i:%s')) |
分区上界生成表达式速查表 - Oracle 模式
| 分区表达式样例 | 说明 | 间隔 | 分区上界计算 SQL 表达式 |
... values less than ('2024') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY''') |
... values less than ('202401') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY"01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYYMM''') |
|
... values less than ('2024-01') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-"01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-MM''') |
|
... values less than ('2024/01') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/"01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/MM''') |
|
... values less than ('20240101') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY"01""01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYYMM"01"''') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYYMMDD''') |
|
... values less than ('2024-01-01') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-"01"-"01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-MM-"01"''') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-MM-DD''') |
|
... values less than ('2024/01/01') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/"01"/"01"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/MM/"01"''') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/MM/DD''') |
|
... values less than ('2024-01-01 00:00:00') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-"01"-"01 00:00:00"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-MM-"01 00:00:00"''') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY-MM-DD "00:00:00"''') |
|
... values less than ('2024/01/01 00:00:00') |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/"01"/"01 00:00:00"''') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/MM/"01 00:00:00"''') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, '''YYYY/MM/DD "00:00:00"''') |
|
... values less than (2024) |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYY') |
... values less than (202401) |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYY"01"') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYYMM') |
|
... values less than (20240101) |
按年生成 | NUMTOYMINTERVAL(1, 'YEAR') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYY"01""01"') |
| 按月生成 | NUMTOYMINTERVAL(1, 'MONTH') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYYMM"01"') |
|
| 按日生成 | NUMTODSINTERVAL(1, 'DAY') |
TO_CHAR(SYSDATE + ${INTERVAL}, 'YYYYMMDD') |
顺序递增分区创建策略
顺序递增只针对时间类型的分区键。
顺序递增的基准时间可以当前时间和指定时间为准,按照用户配置的时间间隔顺序生成新的分区。
分区名生成策略
用户可以通过不同的策略生成分区名,分区名的生成和分区的内容相关联。
分区计划目前提供 2 种分区名生成策略:
前缀加后缀策略:前缀是一个字符串常量,后缀是针对日期型分区表达式的引用,用户可以通过修改前缀和后缀的内容,基准时间以及输出格式来获取不同的分区名。

注意
该策略仅对日期型的分区键有效。后缀引用指定分区键对应的 SQL 表达式的值,由于限定了引用的分区键是时间类型,因此其对应的 SQL 表达式可以被转换成时间,最后再格式化输出为分区名的后缀部分。
自定义策略:该策略通过 SQL 表达式生成符合用户要求的分区名。在命名表达式中可以通过
${分区键}的方式引用分区键对应分区表达式的值。
下述为常见分区名的生成表达式速查表,ODC 仅支持速查数字类型和字符类型的分区键。
分区名生成表达式速查表 - MySQL 模式
| 待引用分区表达式示例 | 命名规则表达式 | 预览 |
... values less than (..., 2024, ...) |
concat('P', ${分区键}) |
P2024 |
... values less than (..., '2024', ...) |
||
... values less than (..., 202401, ...) |
concat('P', ${分区键}) |
P202401 |
... values less than (..., '202401', ...) |
||
... values less than (..., '2024-01', ...) |
date_format(str_to_date(concat(${分区键}, '-01'), '%Y-%m-%d'), 'P%Y%m') |
P202401 |
date_format(str_to_date(concat(${分区键}, '-01'), '%Y-%m-%d'), 'P%Y_%m') |
P2024_01 | |
... values less than (..., '2024/01', ...) |
date_format(str_to_date(concat(${分区键}, '/01'), '%Y/%m/%d'), 'P%Y%m') |
P202401 |
date_format(str_to_date(concat(${分区键}, '/01'), '%Y/%m/%d'), 'P%Y_%m') |
P2024_01 | |
... values less than (..., 20240101, ...) |
concat('P', ${分区键}) |
P20240101 |
... values less than (..., '20240101', ...) |
||
... values less than (..., '2024-01-01', ...) |
date_format(str_to_date(${分区键}, '%Y-%m-%d'), 'P%Y%m%d') |
P20240101 |
date_format(str_to_date(${分区键}, '%Y-%m-%d'), 'P%Y_%m_%d') |
P2024_01_01 | |
... values less than (..., '2024/01/01', ...) |
date_format(str_to_date(${分区键}, '%Y/%m/%d'), 'P%Y%m%d') |
P20240101 |
date_format(str_to_date(${分区键}, '%Y/%m/%d'), 'P%Y_%m_%d') |
P2024_01_01 | |
... values less than (..., '2024-01-01 00:00:00', ...) |
date_format(str_to_date(${分区键}, '%Y-%m-%d %H:%i:%s'), 'P%Y%m%d') |
P20240101 |
date_format(str_to_date(${分区键}, '%Y-%m-%d %H:%i:%s'), 'P%Y_%m_%d') |
P2024_01_01 | |
... values less than (..., '2024/01/01 00:00:00', ...) |
date_format(str_to_date(${分区键}, '%Y/%m/%d %H:%i:%s'), 'P%Y%m%d') |
P20240101 |
date_format(str_to_date(${分区键}, '%Y/%m/%d %H:%i:%s'), 'P%Y_%m_%d') |
P2024_01_01 | |
... values less than (..., 1709222400, ...)注:时间戳,单位:秒 |
date_format(from_unixtime(${分区键}), 'P%Y') |
P2024 |
date_format(from_unixtime(${分区键}), 'P%Y%m') |
P202401 | |
date_format(from_unixtime(${分区键}), 'P%Y_%m') |
P2024_01 | |
date_format(from_unixtime(${分区键}), 'P%Y%m%d') |
P20240101 | |
date_format(from_unixtime(${分区键}), 'P%Y_%m_%d') |
P2024_01_01 |
分区名生成表达式速查表 - Oracle 模式
| 待引用分区表达式示例 | 命名规则表达式 | 预览 |
... values less than (..., 2024, ...) |
concat('P', ${分区键}) |
P2024 |
... values less than (..., '2024', ...) |
||
... values less than (..., 202401, ...) |
concat('P', ${分区键}) |
P202401 |
... values less than (..., '202401', ...) |
||
... values less than (..., '2024-01', ...) |
TO_CHAR(TO_DATE(CONCAT(${分区键}, '-01'), 'YYYY-MM-DD'), '"P"YYYYMM') |
P202401 |
TO_CHAR(TO_DATE(CONCAT(${分区键}, '-01'), 'YYYY-MM-DD'), '"P"YYYY_MM') |
P2024_01 | |
... values less than (..., '2024/01', ...) |
TO_CHAR(TO_DATE(CONCAT(${分区键}, '/01'), 'YYYY/MM/DD'), '"P"YYYYMM') |
P202401 |
TO_CHAR(TO_DATE(CONCAT(${分区键}, '/01'), 'YYYY/MM/DD'), '"P"YYYY_MM') |
P2024_01 | |
... values less than (..., 20240101, ...) |
concat('P', ${分区键}) |
P20240101 |
... values less than (..., '20240101', ...) |
||
... values less than (..., '2024-01-01', ...) |
TO_CHAR(TO_DATE(${分区键}, 'YYYY-MM-DD'), '"P"YYYYMMDD') |
P20240101 |
TO_CHAR(TO_DATE(${分区键}, 'YYYY-MM-DD'), '"P"YYYY_MM_DD') |
P2024_01_01 | |
... values less than (..., '2024/01/01', ...) |
TO_CHAR(TO_DATE(${分区键}, 'YYYY/MM/DD'), '"P"YYYYMMDD') |
P20240101 |
TO_CHAR(TO_DATE(${分区键}, 'YYYY/MM/DD'), '"P"YYYY_MM_DD') |
P2024_01_01 | |
... values less than (..., '2024-01-01 00:00:00', ...) |
TO_CHAR(TO_DATE(${分区键}, 'YYYY-MM-DD HH24:MI:SS'), '"P"YYYYMMDD') |
P20240101 |
TO_CHAR(TO_DATE(${分区键}, 'YYYY-MM-DD HH24:MI:SS'), '"P"YYYY_MM_DD') |
P2024_01_01 | |
... values less than (..., '2024/01/01 00:00:00', ...) |
TO_CHAR(TO_DATE(${分区键}, 'YYYY/MM/DD HH24:MI:SS'), '"P"YYYYMMDD') |
P20240101 |
TO_CHAR(TO_DATE(${分区键}, 'YYYY/MM/DD HH24:MI:SS'), '"P"YYYY_MM_DD') |
P2024_01_01 |
分区删除策略
注意
- 表如果包含全局索引,删除分区会导致全局索引失效,请谨慎操作;如果选择重建全局索引可能因耗时较久导致业务问题,或者重建全局索引失败导致线上问题。
- 重建全局索引选项仅对 Oracle 模式有效,MySQL 模式下无此选项,因 MySQL 模式下默认会重建全局索引。
- 分区删除策略需要考虑预创建分区的影响,避免因为分区预创建而导致的历史分区误删。例如:目标表按月分区,想保留过去 12 个月的分区,分区保留数目 中输入 12,假设此时创建策略预创建 3 个月的分区,那么实际将保留过去 9 个月和未来 3 个月的分区。
分区删除策略是针对已经存在的分区,目前仅支持一种策略:保留最近的 N 个分区,即删除最近 N 个分区外的其它分区。
示例:
创建
order表且表中包含p2023_01、p2023_02两个分区。CREATE TABLE `order` ( `time` date NOT NULL, `parti_key` int(11), `name` varchar(120) DEFAULT NULL ) partition by range columns(time, parti_key) (partition p2023_01 values less than ('2023-01-01', 20230101), partition p2023_02 values less than ('2023-02-01', 20230201))为
order表配置分区删除策略(保留最近 1 个分区)。根据分区删除策略形成的分区删除语句将会删除
p2023_01分区。
注意事项
表如果属于表组(tablegroup),创建分区可能会失败或破坏负载均衡,请谨慎配置创建策略。
新建索引可能会导致表组(tablegroup)失效,因为同属于一个表组的表必须拥有完全一致的分区,而新建分区可能会破坏这种现状,导致表组失效。
表如果包含全局索引,删除分区会导致全局索引失效,请谨慎操作;如果选择重建全局索引可能因耗时较久导致业务问题,或者重建全局索引失败导致线上问题。
重建全局索引选项仅对 Oracle 模式有效,MySQL 模式下无此选项,因 MySQL 模式下默认会重建全局索引。