本文介紹了創建INTERVAL RANGE分區的語法。
前提條件
集群版本需為PolarDB MySQL版8.0.2版本且Revision version為8.0.2.2.0及以上。您可以通過查詢版本號確認集群版本。
語法
CREATE TABLE [IF NOT EXISTS] [schema.]table_name
table_definition
partition_options;
其中,partition_options
為:
PARTITION BY
{ RANGE{(expr) | COLUMNS(column_list)} }
{ INTERVAL(type, expr) | INTERVAL(expr) }
[(partition_definition [, partition_definition] ...)]
partition_definition
為:
PARTITION partition_name
[VALUES LESS THAN {expr | MAXVALUE}]
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
其中,INTERVAL
子句僅支持設置間隔數值(expr
)和間隔類型(type
)。
參數
參數 | 參數說明 |
table_name | 要創建的表名稱。 |
RANGE(expr) | RANGE分區字段表達式,目前只支持INT類型,不支持字符類型。 |
column_list | RANGE COLUMNS的情況下使用,分區字段列表,不支持表達式。 |
INTERVAL(type) | 目前支持8種時間類型(YEAR、QUARTER、MONTH、WEEK、DAY、HOUR、MINUTE、SECOND),不顯式指定默認是數字類型的間隔。 |
INTERVAL(expr) | 指定間隔的數值大小。當type為SECOND類型時,間隔不能小于60。 |
MAXVALUE | 最大值。 |
engine_name | 存儲引擎名稱。 |
間隔數值(expr)
相近的1000個數字進入同一個分區,示例如下:
INTERVAL(1000)
時間類型
年(YEAR)
以年為單位設置自動分區的間隔,每一年的數據進入同一個分區,示例如下:
INTERVAL(YEAR, 1)
季度(QUARTER)
以季度為單位設置自動分區的間隔,每一季度的數據進入同一個分區,示例如下:
INTERVAL(QUARTER, 1)
月(MONTH)
以月為單位設置自動分區的間隔,每一月的數據進入同一個分區,示例如下:
INTERVAL(MONTH, 1)
周(WEEK)
以周為單位設置自動分區的間隔,每一周的數據進入同一個分區,示例如下:
INTERVAL(WEEK, 1)
日(DAY)
以日為單位設置自動分區的間隔,每一日的數據進入同一個分區,示例如下:
INTERVAL(DAY, 1)
時(HOUR)
以小時為單位設置自動分區的間隔,每一小時的數據進入同一個分區,示例如下:
INTERVAL(HOUR, 1)
分(MINUTE)
以分鐘為單位設置自動分區的間隔,每一分鐘的數據進入同一個分區,示例如下:
INTERVAL(MINUTE, 1)
秒(SECOND)
以秒為單位設置自動分區的間隔,每60秒的數據進入同一個分區,示例如下:
INTERVAL(SECOND, 60)
示例
以下示例將order_time
作為分區鍵,按間隔劃分sales
表。創建INTERVAL RANGE分區表需要有一個初始的轉換點,然后才能在轉換點之外自動創建新的分區。
在數據庫中創建一個新的INTERVAL RANGE分區表,并向表中插入數據,示例如下:
CREATE TABLE sales
(
id BIGINT,
uid BIGINT,
order_time DATETIME
)
PARTITION BY RANGE COLUMNS(order_time) INTERVAL(MONTH, 1)
(
PARTITION p0 VALUES LESS THAN('2021-9-1')
);
向INTERVAL RANGE分區表中插入數據。示例如下:
INSERT INTO sales VALUES(1, 1010101010, '2021-11-11');
插入數據后,SHOW CREATE TABLE查詢sales
表定義。新的表定義如下:
CREATE TABLE `sales` (
`id` bigint(20) DEFAULT NULL,
`uid` bigint(20) DEFAULT NULL,
`order_time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE COLUMNS(order_time) */ /*!99990 800020200 INTERVAL(MONTH, 1) */
/*!50500 (PARTITION p0 VALUES LESS THAN ('2021-9-1') ENGINE = InnoDB,
PARTITION _p20211001000000 VALUES LESS THAN ('2021-10-01 00:00:00') ENGINE = InnoDB,
PARTITION _p20211101000000 VALUES LESS THAN ('2021-11-01 00:00:00') ENGINE = InnoDB,
PARTITION _p20211201000000 VALUES LESS THAN ('2021-12-01 00:00:00') ENGINE = InnoDB) */
通過上述示例發現INTERVAL RANGE分區自動新增加了_p20211001000000、_p20211101000000、_p20211201000000三個分區,這里要注意‘_p’作為前綴的分區名將會保留為系統命名規則,手動管理分區(創建新分區或者重命名分區的操作)時,將不允許使用此類型的分區名。例如,ADD PARTITION
和REORGANIZE PARTITION
操作將不允許使用‘_p’作為前綴的分區名;但是DROP PARTITION
操作可以使用‘_p’作為前綴的分區名。
在上述業務場景下,此前通常需要DBA在插入值觸及轉換點之前手動增加分區,稍有疏忽就有可能導致新的數據插入失敗。通過創建INTERVAL RANGE分區表,可以由系統自動增加分區,避免數據不能及時插入。
由于分區數量最多只能達到8192,自動增加分區的數量也會受限制。因此建議您配合分區表的生命周期管理解決方案使用,定期增加分區,同時定期將冷數據所在的分區自動遷移到OSS上。
更多示例如下:
/* 設定間隔為數字類型,大小為1000 */
CREATE TABLE t(a int, b datetime)
PARTITION BY RANGE(a) INTERVAL(1000) (
PARTITION p0 VALUES LESS THAN(1000)
);
/* 由于partition expression只能是INT_RESULT,所以不需要顯式指定type,設定大小即可 */
CREATE TABLE t(a int, b datetime)
PARTITION BY RANGE(MONTH(b)) INTERVAL(1) (
PARTITION p0 VALUES LESS THAN(2)
);
/* 由于分區鍵不是時間類型,設定間隔為數字類型,大小為1000 */
CREATE TABLE t(a int, b datetime)
PARTITION BY RANGE COLUMNS(a) INTERVAL(1000) (
PARTITION p0 VALUES LESS THAN(1000)
);
/* 設定間隔為1年 */
CREATE TABLE t(a int, b datetime)
PARTITION BY RANGE COLUMNS(b) INTERVAL(YEAR, 1) (
PARTITION p0 VALUES LESS THAN('2021-11-01 00:00:00')
);