本文主要介绍了在AUTO模式数据库下主键拆分表的自动分区规则和索引变换规则。
在自动分区模式的数据库中,如不手动指定分区方式,默认按主键进行拆分。
前提条件
- PolarDB-X版本为5.4.13及以上。
- 创建数据库时选择了AUTO模式,即“MODE”选择为“auto/partitioning”,关于创建数据库时的模式选择,请参见CREATE DATABASE。
注意事项
- 除去创建表时指定为单表或广播表,其他表都默认创建为分区表,如不手动指定分区方式,默认按主键进行拆分。
- 主键拆分表仅支持在建表时指定主键,不支持对已有的表添加或删除主键。如果建表时没有指定主键,则会自动创建隐式主键。
- 主键拆分表的索引除非第一列不支持自动分区或指定为LOCAL索引,否则自动创建为全局二级索引。
- 分区策略变更后,主键拆分表将变成普通表(即不再适用原主键拆分表中的自动分区策略或索引转换规则)。如何变更分区策略,请参见变更表类型及分区策略。
- 自动分区数据库中,GSI名称不再要求唯一,建表语句中也不再要求强制指定GSI名称。所有GSI表会携带随机后缀,使用
show full create table
可以看到这些随机后缀。
语法
自动分区模式下的主键拆分会默认开启,建表语句无需添加特殊关键字,建表语法参见 CREATE TABLE。
下面通过几个例子展示分区效果,其中show create table
会显示表的精简结构信息,而show full create table
会显示完整的表结构。
CREATE TABLE `tb` (
-> `x` int NOT NULL AUTO_INCREMENT,
-> `y` int NOT NULL,
-> `z` float NOT NULL,
-> `d` int NOT NULL,
-> PRIMARY KEY (x,y,z,d)
-> );
Query OK, 0 rows affected (0.42 sec)
show create table tb;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb | CREATE TABLE `tb` (
`x` int(11) NOT NULL AUTO_INCREMENT,
`y` int(11) NOT NULL,
`z` float NOT NULL,
`d` int(11) NOT NULL,
PRIMARY KEY (`x`, `y`, `z`, `d`),
LOCAL KEY `auto_shard_key_x_y_d` USING BTREE (`x`, `y`, `d`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
show full create table tb;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb | CREATE PARTITION TABLE `tb` (
`x` int(11) NOT NULL AUTO_INCREMENT,
`y` int(11) NOT NULL,
`z` float NOT NULL,
`d` int(11) NOT NULL,
PRIMARY KEY (`x`, `y`, `z`, `d`),
LOCAL KEY `auto_shard_key_x_y_d` USING BTREE (`x`, `y`, `d`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`x`,`y`,`d`)
PARTITIONS 16
/* tablegroup = `tg8` */ |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
CREATE TABLE `t_order` (
-> `x` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> `order_id` varchar(20) DEFAULT NULL,
-> `seller_id` varchar(20) DEFAULT NULL,
-> INDEX (`seller_id`),
-> UNIQUE INDEX (`order_id`)
-> );
Query OK, 0 rows affected (0.84 sec)
show create table `t_order`;
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_order | CREATE TABLE `t_order` (
`x` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(20) DEFAULT NULL,
`seller_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`x`),
INDEX `i_0` (`seller_id`),
UNIQUE INDEX `i_1` (`order_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
show full create table `t_order`;
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_order | CREATE PARTITION TABLE `t_order` (
`x` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(20) DEFAULT NULL,
`seller_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`x`),
GLOBAL INDEX /* i_0_$cff4 */ `i_0` (`seller_id`) PARTITION BY KEY (`seller_id`, `x`) PARTITIONS 16,
UNIQUE GLOBAL INDEX /* i_1_$1782 */ `i_1` (`order_id`) PARTITION BY KEY (`order_id`) PARTITIONS 16,
UNIQUE LOCAL KEY `_local_i_1` (`order_id`),
LOCAL KEY `_local_i_0` (`seller_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`x`)
PARTITIONS 16
/* tablegroup = `tg8` */ |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
自动分区规则
- 如果目标表没有指定主键,PolarDB-X会启用隐式主键并将其作为拆分键,该主键为BIGINT类型的自增主键,且对用户不可见,使用
show full create table
可以查看完整的分区细节。 - 如果目标表指定了主键,PolarDB-X会使用该主键作为拆分键。如果为复合主键,会使用复合主键的所有列作为拆分键。
- 对于复合主键,按顺序作为KEY拆分方式的参数,如果遇到不支持的类型则跳过该列,如果第一列就不支持则会报错,必须手动指定为SINGLE表才能创建成功,SINGLE表建表语句参见单表与广播表。
- 自动分区使用分区表拆分算法,且拆分算法根据主键类型自动选择:
主键类型 | 拆分算法 |
---|---|
bit, float, double, time, year, tinyblob, blob, mediumblob, longblob, enum, decimal, binary, varbinary, tinytext, text, mediumtext, longtext, set, geometry | 不支持 |
其他 | KEY分区 |
索引转换规则
主键拆分表上创建索引,除非明确指定为LOCAL索引,否则会自动转换为全局二级索引,具体转换规则如下:
- 如果指定了LOCAL关键字,即强制指定索引为本地索引。
- 对主键拆分表执行创建索引操作时,如果未指定LOCAL关键字,该操作将被自动地转变为创建无覆盖列(covering)的全局二级索引,并且索引列会依据上述的自动分区规则进行自动分区。如果需要建立普通的局部索引,您需要指定LOCAL关键字。
- 在对全局二级索引生成拆分算法时,会使用全部的索引键进行拆分,同时,对于非UNIQUE约束,会附带上主键作为拆分算法参数。
- 创建全局二级索引和聚簇索引时,会创建一个带 _local_ 前缀的本地索引。如果删除全局二级索引,PolarDB-X会自动同步删除对应的本地索引。
- 主键拆分表可以不指定全局二级索引、聚簇索引的分区方式,PolarDB-X会根据自动分区原则对索引键执行分区。
下述语句及其注释为您展示了索引的转换规则。
CREATE PARTITION TABLE `t_order` (
-> `x` int,
-> `order_id` varchar(20) DEFAULT NULL,
-> `seller_id` varchar(20) DEFAULT NULL,
-> LOCAL INDEX `l_seller` using btree (`seller_id`), -- 强制指定为本地索引
-> UNIQUE LOCAL INDEX `l_order` using btree (`order_id`), -- 强制指定为本地唯一索引
-> INDEX `i_seller` using btree (`seller_id`), -- 会被替换为GSI,自动分区
-> UNIQUE INDEX `i_order` using btree (`order_id`), -- 会被替换为UGSI,自动分区
-> GLOBAL INDEX `g_seller` using btree (`seller_id`), -- 自动分区
-> UNIQUE GLOBAL INDEX `g_order` using btree (`order_id`), -- 自动分区
-> CLUSTERED INDEX `c_seller` using btree (`seller_id`), -- 自动分区聚簇
-> UNIQUE CLUSTERED INDEX `c_order` using btree (`order_id`) -- 自动分区聚簇
-> );
Query OK, 0 rows affected (1.49 sec)
show create table `t_order`;
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_order | CREATE TABLE `t_order` (
`x` int(11) DEFAULT NULL,
`order_id` varchar(20) DEFAULT NULL,
`seller_id` varchar(20) DEFAULT NULL,
UNIQUE CLUSTERED INDEX `c_order` USING BTREE (`order_id`),
CLUSTERED INDEX `c_seller` USING BTREE (`seller_id`),
UNIQUE INDEX `g_order` USING BTREE (`order_id`),
INDEX `g_seller` USING BTREE (`seller_id`),
UNIQUE INDEX `i_order` USING BTREE (`order_id`),
INDEX `i_seller` USING BTREE (`seller_id`),
UNIQUE LOCAL KEY `l_order` USING BTREE (`order_id`),
LOCAL KEY `l_seller` USING BTREE (`seller_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
show full create table `t_order`;
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_order | CREATE PARTITION TABLE `t_order` (
`x` int(11) DEFAULT NULL,
`order_id` varchar(20) DEFAULT NULL,
`seller_id` varchar(20) DEFAULT NULL,
`_drds_implicit_id_` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`_drds_implicit_id_`),
UNIQUE CLUSTERED INDEX /* c_order_$1ba0 */ `c_order` USING BTREE (`order_id`) PARTITION BY KEY (`order_id`) PARTITIONS 16,
CLUSTERED INDEX /* c_seller_$1e39 */ `c_seller` USING BTREE (`seller_id`) PARTITION BY KEY (`seller_id`, `_drds_implicit_id_`) PARTITIONS 16,
UNIQUE GLOBAL INDEX /* g_order_$d57f */ `g_order` USING BTREE (`order_id`) PARTITION BY KEY (`order_id`) PARTITIONS 16,
GLOBAL INDEX /* g_seller_$6ed5 */ `g_seller` USING BTREE (`seller_id`) PARTITION BY KEY (`seller_id`, `_drds_implicit_id_`) PARTITIONS 16,
UNIQUE GLOBAL INDEX /* i_order_$ab2f */ `i_order` USING BTREE (`order_id`) PARTITION BY KEY (`order_id`) PARTITIONS 16,
GLOBAL INDEX /* i_seller_$2b4b */ `i_seller` USING BTREE (`seller_id`) PARTITION BY KEY (`seller_id`, `_drds_implicit_id_`) PARTITIONS 16,
UNIQUE LOCAL KEY `l_order` USING BTREE (`order_id`),
UNIQUE LOCAL KEY `_local_i_order` USING BTREE (`order_id`),
UNIQUE LOCAL KEY `_local_g_order` USING BTREE (`order_id`),
UNIQUE LOCAL KEY `_local_c_order` USING BTREE (`order_id`),
LOCAL KEY `l_seller` USING BTREE (`seller_id`),
LOCAL KEY `_local_i_seller` USING BTREE (`seller_id`),
LOCAL KEY `_local_g_seller` USING BTREE (`seller_id`),
LOCAL KEY `_local_c_seller` USING BTREE (`seller_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`_drds_implicit_id_`)
PARTITIONS 16
/* tablegroup = `tg11` */ |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
主键拆分表的DDL限制
如需对主键拆分表执行下述DDL操作,存在一些限制。
DDL类别 | DDL子句 | 说明与限制 |
---|---|---|
CREATE INDEX | 无 |
|
ALTER TABLE | ADD {INDEX | KEY} [index_name] [index_type] (key_part,...) [index_option] ... | |
ADD [COLUMN] (col_name column_definition,...) |
|
|
DROP [COLUMN] col_name | 不允许删除主键、主表拆分键、索引表拆分键和复合UNIQUE约束中的列。 | |
CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST | AFTER col_name] |
|
|
MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name] | ||
ALTER TABLE tbl_name ALTER [COLUMN] col_name { SET DEFAULT {literal | (expr)} | DROP DEFAULT } | 支持回滚操作。
说明 如果列的默认值为current_timestamp,则不支持回滚操作。
|