This reference covers the CREATE TABLE syntax for creating partitioned tables in PolarDB-X databases running in AUTO mode, including partitioning types, parameters, constraints, and data routing behavior.
This syntax applies only to logical databases created withmode='auto'. RunSHOW CREATE DATABASE db_nameto check the mode of an existing database.
Prerequisites
Before creating a partitioned table:
The target logical database must be set to AUTO mode. To create one:
CREATE DATABASE part_db mode='auto';To use level-2 partition features, your PolarDB-X instance must be version 5.4.17-16952556 or later.
If the primary key does not include the partition key and is not an auto-increment primary key, the primary key must be unique.
Key concepts
| Term | Definition |
|---|---|
| Partition key | One or more columns used to horizontally split a table across partitions |
| Partition key column | A single column that is part of a partition key |
| Single-column partition key | A partition key with exactly one column |
| Vector partition key | A partition key with two or more columns |
| Prefix partition key column | In a vector partition key of N columns, the first K columns (1 ≤ K ≤ N) |
| Partition function | A function applied to a partition key column before routing. See Partition functions |
| Partition pruning | Query optimization that skips partitions not matching the WHERE condition |
| Hot partition splitting | Splitting a hot partition into multiple partitions using another column in a vector partition key |
| Physical partition | A partition stored on a data node; corresponds to one physical table shard |
| Logical partition | A virtual partition that maps to one or more physical partitions (level-1 partition in a level-2 setup) |
Choose a partitioning type
| Goal | Recommended type |
|---|---|
| Distribute writes evenly with no range semantics | KEY (default) or HASH |
| Partition by date or time ranges | RANGE with a partition function (e.g., YEAR, TO_DAYS) |
| Partition by discrete categorical values | LIST or LIST COLUMNS |
| Partition by time ranges with multi-column keys | RANGE COLUMNS |
Partition by multiple columns with correlated values (e.g., order_id and buyer_id sharing a suffix) | COHASH |
| Add a second dimension to any of the above | Level-2 partitions (subpartitions) |
Syntax
CREATE [PARTITION] TABLE [IF NOT EXISTS] tbl_name
(create_definition, ...)
[table_options]
[table_partition_definition]
[local_partition_definition]Where table_partition_definition is one of:
SINGLE
| BROADCAST
| partition_optionsAnd partition_options is:
partition_columns_definition
[subpartition_columns_definition]
[subpartition_specs_definition] -- templated level-2 partitions
partition_specs_definitionPartition key column definitions (level-1)
PARTITION BY
HASH({column_name | partition_func(column_name)}) PARTITIONS n
| KEY(column_list) PARTITIONS n
| RANGE ({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST ({column_name | partition_func(column_name)})
| LIST COLUMNS(column_list)
| CO_HASH({column_expr_list}) PARTITIONS nPartition key column definitions (level-2)
Same options as level-1, except CO_HASH is not supported:
SUBPARTITION BY
HASH({column_name | partition_func(column_name)}) SUBPARTITIONS n
| KEY(column_list) SUBPARTITIONS n
| RANGE ({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST ({column_name | partition_func(column_name)})
| LIST COLUMNS(column_list)Global secondary index
[UNIQUE] GLOBAL INDEX index_name [index_type] (index_sharding_col_name,...)
[COVERING (col_name,...)]
[partition_options]
[VISIBLE|INVISIBLE]Table options
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string']
[{CHARSET | CHARACTER SET} [=] charset]
[COLLATE [=] collation]
[TABLEGROUP [=] table_group_id]
[LOCALITY [=] 'dn=storage_inst_id_list']Local partition definition
LOCAL PARTITION BY RANGE (column_name)
[STARTWITH 'yyyy-MM-dd']
INTERVAL interval_count [YEAR|MONTH|DAY]
[EXPIRE AFTER expire_after_count]
[PRE ALLOCATE pre_allocate_count]
[PIVOTDATE {NOW() | DATE_ADD(...) | DATE_SUB(...)}]
[DISABLE SCHEDULE]PolarDB-X DDL syntax is based on MySQL. The sections below highlight the differences. For the base MySQL syntax, see MySQL 5.7 CREATE TABLE documentation.
Parameters
| Parameter | Description |
|---|---|
CHARSET / CHARACTER SET | Default character set for table columns. Supported values: utf8, utf8mb4, gbk |
COLLATE | Default collation for table columns. Supported values: utf8_bin, utf8_general_ci, utf8_unicode_ci, gbk_bin, gbk_chinese_ci, utf8mb4_general_ci, utf8mb4__general_cs, utf8mb4_bin, utf8mb4_unicode_ci |
TABLEGROUP | Table group to which the table belongs. If omitted, PolarDB-X assigns the table to an existing compatible table group or creates a new one. All tables in a group must use the same partitioning method |
LOCALITY | Data nodes where the table is deployed |
Partition functions
The following functions can be used inside PARTITION BY HASH(...), PARTITION BY RANGE(...), and PARTITION BY LIST(...) to transform a column value before routing:
YEAR · MONTH · DAYOFMONTH · DAYOFWEEK · DAYOFYEAR · TO_DAYS · TO_MONTHS · TO_WEEKS · TO_SECOND · UNIX_TIMESTAMP · SUBSTR / SUBSTRING · RIGHT · LEFT
SUBSTRandSUBSTRINGrequire a STRING column.All other functions require a DATE, DATETIME, or TIMESTAMP column.
Nested functions are not supported (e.g.,
SUBSTR(SUBSTR(c1,-6),-4)).
Non-partitioned tables
Use the SINGLE keyword to create a table that is not distributed across partitions:
CREATE TABLE single_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) SINGLE;Broadcast tables
Use the BROADCAST keyword to replicate a table to every data node. This is useful for small reference tables that are frequently joined with large partitioned tables:
CREATE TABLE broadcast_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) BROADCAST;Partitioned tables
HASH partitioning and KEY partitioning
Both types distribute data using PolarDB-X's built-in MurmurHash3 consistent hashing algorithm. Data distribution becomes balanced when the partition key has more than 3,000 distinct values.
The two types differ in how they handle multi-column partition keys:
| KEY partitioning | HASH partitioning | |
|---|---|---|
| Syntax | PARTITION BY KEY(c1, ..., cn) | PARTITION BY HASH(c1) or PARTITION BY HASH(c1, ..., cn) |
| Single-column key | Supported | Supported |
| Vector partition key | Supported (routes by first K columns; other columns available for hot partition splitting) | Supported (routes by all columns simultaneously; hot partition splitting not available) |
| Partition functions | Not supported | Supported for single-column keys |
| Default type | Yes — KEY is the default | No |
Example: KEY partitioning (recommended for most use cases)
Create a table partitioned by name and id. By default, routing uses only the name column, leaving id available for hot partition splitting later:
CREATE TABLE key_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY KEY(name, id)
PARTITIONS 8;To trigger partition pruning, include the first routing column in the WHERE clause:
-- Scans only one partition
SELECT id FROM key_tbl WHERE name = 'Jack';If the name column develops a hot spot, use ALTER TABLEGROUP to split on the id column. For details, see ALTER TABLEGROUP.
Example: HASH partitioning (single-column)
CREATE TABLE hash_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(id)
PARTITIONS 8;To partition by a datetime column, use a partition function to convert it to an integer:
CREATE TABLE hash_tbl_days(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(TO_DAYS(birthday))
PARTITIONS 8;Example: HASH partitioning (vector key)
PolarDB-X extends HASH partitioning to support vector partition keys (not available in MySQL). Unlike KEY partitioning, routing uses all partition key columns simultaneously, so partition pruning requires conditions on all of them:
CREATE TABLE hash_tbl2(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(name, birthday)
PARTITIONS 8;-- Partition pruning: scans one partition (all key columns specified)
SELECT id FROM hash_tbl2 WHERE name = 'Jack' AND birthday = '1990-11-11';
-- No pruning: scans all partitions (incomplete key)
SELECT id FROM hash_tbl2 WHERE name = 'Jack';When to use
KEY partitioning — default choice for even data distribution with the option to split hot partitions later.
HASH with a partition function — when you want to distribute rows by a time component (e.g., year, month) rather than the raw timestamp.
HASH with a vector key — when rows must route by the combined value of multiple columns and you do not need to split hot partitions.
Limitations
Data types
Integer: BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT, TINYINT UNSIGNED
Date/time: DATE, DATETIME, TIMESTAMP
String: CHAR, VARCHAR
Syntax constraints
Single-column keys with a DATE, DATETIME, or TIMESTAMP column may use partition functions.
Vector partition keys do not support partition functions or hot partition splitting.
A table can have at most 8,192 partitions by default.
A partition key can have at most 5 columns.
RANGE partitioning and RANGE COLUMNS partitioning
Both types route data by comparing a partition key value against predefined boundaries. Use RANGE COLUMNS when the key contains multiple columns or string values; use RANGE when you need a partition function on a single date/time column.
| RANGE COLUMNS | RANGE | |
|---|---|---|
| Syntax | PARTITION BY RANGE COLUMNS(c1, ..., cn) | PARTITION BY RANGE(expr(c1)) |
| Vector partition key | Supported | Not supported |
| Partition functions | Not supported | Supported |
| TIMESTAMP columns | Not supported as partition key | Not supported directly; use UNIX_TIMESTAMP() |
| String columns | Supported | Not supported |
| Hot partition splitting | Supported | Not supported |
| Routing algorithm | Binary search | Binary search |
Example: RANGE COLUMNS partitioning
Partition an orders table by order_id and order_time ranges:
CREATE TABLE orders(
order_id int,
order_time datetime not null
)
PARTITION BY RANGE COLUMNS(order_id, order_time)
(
PARTITION p1 VALUES LESS THAN (10000, '2021-01-01'),
PARTITION p2 VALUES LESS THAN (20000, '2021-01-01'),
PARTITION p3 VALUES LESS THAN (30000, '2021-01-01'),
PARTITION p4 VALUES LESS THAN (40000, '2021-01-01'),
PARTITION p5 VALUES LESS THAN (50000, '2021-01-01'),
PARTITION p6 VALUES LESS THAN (MAXVALUE, MAXVALUE)
);RANGE COLUMNS does not support TIMESTAMP or TIME columns as partition key columns.
Example: RANGE partitioning
Partition by quarter using TO_DAYS() to convert order_time to an integer:
CREATE TABLE orders_quarterly(
id int,
order_time datetime not null
)
PARTITION BY RANGE(TO_DAYS(order_time))
(
PARTITION p1 VALUES LESS THAN (TO_DAYS('2021-01-01')),
PARTITION p2 VALUES LESS THAN (TO_DAYS('2021-04-01')),
PARTITION p3 VALUES LESS THAN (TO_DAYS('2021-07-01')),
PARTITION p4 VALUES LESS THAN (TO_DAYS('2021-10-01')),
PARTITION p5 VALUES LESS THAN (TO_DAYS('2022-01-01')),
PARTITION p6 VALUES LESS THAN (MAXVALUE)
);RANGE partitioning requires an integer partition key column. String columns are not supported. To use a TIMESTAMP column, apply UNIX_TIMESTAMP().
When to use
RANGE COLUMNS — date or ID range partitioning with multi-column keys or hot partition splitting requirements.
RANGE — single-column date-based partitioning where you want to use a time extraction function.
Limitations
Data types
Integer: BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT, TINYINT UNSIGNED
Date/time: DATE, DATETIME (TIMESTAMP not supported in RANGE COLUMNS; use UNIX_TIMESTAMP() in RANGE)
String: CHAR, VARCHAR (RANGE COLUMNS only; not supported in RANGE)
Syntax constraints
NULLcannot be used as a range boundary.If a query specifies
NULLfor a RANGE partition key, PolarDB-X treats the NULL as the minimum value during routing.A table can have at most 8,192 partitions by default.
A partition key can have at most 5 columns.
LIST partitioning and LIST COLUMNS partitioning
Both types route each row to the partition whose value list contains the row's partition key value. This is suitable for distributing data by category (region, status, tenant).
| LIST COLUMNS | LIST | |
|---|---|---|
| Syntax | PARTITION BY LIST COLUMNS(c1, ..., cn) | PARTITION BY LIST(expr(c1)) |
| Vector partition key | Supported | Not supported |
| Partition functions | Not supported | Supported |
| TIMESTAMP columns | Not supported | Not supported directly |
| String columns | Supported | Not supported |
| DEFAULT partition | Supported | Supported |
| Hot partition splitting | Not supported | Not supported |
Example: LIST COLUMNS partitioning
Partition a regional orders table by country and city:
CREATE TABLE orders_region(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null
)
PARTITION BY LIST COLUMNS(country, city)
(
PARTITION p1 VALUES IN (('China', 'Hangzhou'), ('China', 'Beijing')),
PARTITION p2 VALUES IN (('United States', 'New York'), ('United States', 'Chicago')),
PARTITION p3 VALUES IN (('Russia', 'Moscow'))
);LIST COLUMNS does not support TIMESTAMP or TIME columns as partition key columns.
Example: LIST partitioning
Partition by year using YEAR() to extract an integer from order_time:
CREATE TABLE orders_by_year(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null
)
PARTITION BY LIST(YEAR(order_time))
(
PARTITION p1 VALUES IN (1990,1991,1992,1993,1994,1995,1996,1997,1998,1999),
PARTITION p2 VALUES IN (2000,2001,2002,2003,2004,2005,2006,2007,2008,2009),
PARTITION p3 VALUES IN (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019)
);LIST partitioning requires integer partition key columns. String columns are not supported.
Example: DEFAULT partition (LIST COLUMNS)
Add a DEFAULT partition to catch rows that do not match any other partition. Only one DEFAULT partition is allowed, and it must be defined last:
CREATE TABLE orders_region_default(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null
)
PARTITION BY LIST COLUMNS(country, city)
(
PARTITION p1 VALUES IN (('China', 'Hangzhou'), ('China', 'Beijing')),
PARTITION p2 VALUES IN (('United States', 'New York'), ('United States', 'Chicago')),
PARTITION p3 VALUES IN (('Russia', 'Moscow')),
PARTITION pd VALUES IN (DEFAULT)
);Example: DEFAULT partition (LIST)
LIST partitioning also supports a DEFAULT partition to route unmatched integer values:
CREATE TABLE orders_by_year_default(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null
)
PARTITION BY LIST(YEAR(order_time))
(
PARTITION p1 VALUES IN (1990,1991,1992,1993,1994,1995,1996,1997,1998,1999),
PARTITION p2 VALUES IN (2000,2001,2002,2003,2004,2005,2006,2007,2008,2009),
PARTITION p3 VALUES IN (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019),
PARTITION pd VALUES IN (DEFAULT)
);When to use
LIST COLUMNS — categorical partitioning on string columns (e.g., country, region) or on multiple columns.
LIST — categorical partitioning on a single integer or time-derived integer column.
Add a DEFAULT partition when new category values may appear after table creation.
Limitations
Data types
Integer: BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT, TINYINT UNSIGNED
Date/time: DATE, DATETIME
String: CHAR, VARCHAR (LIST COLUMNS only)
Syntax constraints
LIST COLUMNS does not support TIMESTAMP columns.
LIST partitioning requires integer partition key columns.
Neither type supports hot partition splitting.
A table can have at most 8,192 partitions by default.
A partition key can have at most 5 columns.
COHASH partitioning
COHASH is a PolarDB-X–exclusive partitioning type for tables where two or more columns always share a common suffix or prefix — for example, order_id and buyer_id always have the same last six digits. COHASH partitions the table so that equivalent queries on any of those columns route to the same partition.
Minimum version: 5.4.18-17047709
How it works
COHASH applies a partition function (such as RIGHT, LEFT, or SUBSTR) to each partition key column to extract the shared portion, then uses consistent hashing on the result. Because the shared portion is identical across columns, rows land in the same partition regardless of which column you query.
Example: COHASH partitioning
Partition an orders table by the last six characters of both order_id and buyer_id:
CREATE TABLE t_orders(
id bigint not null auto_increment,
order_id bigint,
buyer_id bigint,
order_time datetime not null,
primary key(id)
)
PARTITION BY CO_HASH(
RIGHT(order_id, 6), -- last six characters of order_id
RIGHT(buyer_id, 6) -- last six characters of buyer_id
)
PARTITIONS 8;When order_id and buyer_id share the same last six characters, both of the following queries route to the same partition:
SELECT * FROM t_orders WHERE order_id = 100234;
SELECT * FROM t_orders WHERE buyer_id = 100234;Migrating from PolarDB-X 1.0 RANGE_HASH
If the source instance uses RANGE_HASH(order_id, buyer_id, 6), use the same syntax in the destination database. PolarDB-X automatically converts it to the equivalent CO_HASH definition:
CREATE TABLE orders(
id bigint not null auto_increment,
buyer_id bigint,
order_id bigint,
primary key(id)
)
PARTITION BY RANGE_HASH(order_id, buyer_Id, 6)
PARTITIONS 8;COHASH vs KEY vs HASH
| CO_HASH | KEY | HASH | |
|---|---|---|---|
| Single-column key | Not supported | Supported | Supported |
| Vector partition key | Supported | Supported | Supported |
| Partition functions on vector key columns | Supported (e.g., RIGHT(c1,4)) | Not supported | Not supported |
| Partition pruning on any key column | Supported — each column routes independently | Supported on prefix columns only | Supported on all columns together only |
| Hot partition splitting | Not supported | Supported | Not supported |
Usage notes
You are responsible for maintaining column similarity. PolarDB-X checks routing results but does not enforce that the designated similar portion is identical across columns. If an inserted row has differing values in the similar portion, it may be silently routed to an unexpected partition.
DML constraints. To prevent inconsistent routing:
An
INSERTorREPLACEwhere the partition key columns in a row route to different partitions is rejected.An
UPDATEorUPSERTthat modifies partition key columns must update all of them. If the new values route to different partitions, the statement is rejected.The same restrictions apply to DML on the primary table when the table has a COHASH global secondary index (GSI).
Leading zeros in integer columns. When a partition function like
RIGHT(c1, 4)is applied to an integer column, the result is automatically converted to its numeric value (e.g.,'0034'becomes34). This ensures thatc1 = 1000034andc2 = 34route to the same partition as expected.
When to use
Use COHASH when a table has two or more columns whose values are always correlated by a shared suffix or prefix, and you need equivalent point queries on any of those columns to hit a single partition.
Limitations
Partition functions: RIGHT, LEFT, SUBSTR only. Nested functions are not supported.
Data types: BIGINT, INT, MEDIUMINT, SMALLINT, TINYINT (and UNSIGNED variants); DECIMAL (decimal part must be zero); CHAR, VARCHAR. Date/time types are not supported.
Syntax constraints
All partition key columns must share the same character set, collation, and length/precision definition.
When using
RANGE_HASHsyntax, the length value must be positive.A table can have at most 8,192 partitions by default.
A partition key can have at most 5 columns.
Level-2 partitions (subpartitions)
Level-2 partitions add a second partitioning dimension to every level-1 partition. The level-1 partitions become logical partitions; each level-2 subpartition is a physical partition on a data node.
Level-2 partition features require PolarDB-X version 5.4.17-16952556 or later.
Templated vs non-templated subpartitions
Templated: every level-1 partition gets the same number and boundary of subpartitions. Defined using
SUBPARTITION BY ... SUBPARTITIONS nbefore the partition list.Non-templated: each level-1 partition can have a different number of subpartitions. Defined by specifying
SUBPARTITIONS ninside eachPARTITIONclause.
Example: Templated subpartitions
Three LIST COLUMNS level-1 partitions, each with four KEY subpartitions — 12 physical partitions total:
CREATE TABLE sp_tbl_list_key_tp(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null,
PRIMARY KEY(id)
)
PARTITION BY LIST COLUMNS(country, city)
SUBPARTITION BY KEY(id) SUBPARTITIONS 4
(
PARTITION p1 VALUES IN (('China', 'Hangzhou')),
PARTITION p2 VALUES IN (('Russia', 'Moscow')),
PARTITION pd VALUES IN (DEFAULT)
);Example: Non-templated subpartitions
Three LIST COLUMNS level-1 partitions with 2, 3, and 4 subpartitions respectively — 9 physical partitions total:
CREATE TABLE sp_tbl_list_key_ntp(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null,
PRIMARY KEY(id)
)
PARTITION BY LIST COLUMNS(country, city)
SUBPARTITION BY KEY(id)
(
PARTITION p1 VALUES IN (('China', 'Hangzhou')) SUBPARTITIONS 2,
PARTITION p2 VALUES IN (('Russia', 'Moscow')) SUBPARTITIONS 3,
PARTITION pd VALUES IN (DEFAULT) SUBPARTITIONS 4
);When to use
Use level-2 partitions when a single-dimensional partition strategy leads to data skew or insufficient granularity — for example, partitioning orders by region (LIST) and then by ID within each region (KEY).
Limitations
The total number of physical partitions (the sum of all level-2 partitions across all level-1 partitions) cannot exceed 8,192 by default.
Subpartition names must be unique and cannot duplicate any level-1 partition name.
Keep the product of level-1 and level-2 counts small to avoid excessive partition overhead.
Automatic partitioning
By default, automatic partitioning is disabled for AUTO mode databases. To enable it:
SET GLOBAL AUTO_PARTITION = true;With automatic partitioning enabled, a CREATE TABLE statement without an explicit partition key uses KEY partitioning on the primary key. The default partition count is: number of logical nodes × 8. For a 2-node instance, that is 16 partitions.
All secondary indexes on an automatically partitioned table are created as global secondary indexes (GSIs), partitioned by the index key column and the primary key column.
Example
CREATE TABLE auto_part_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id),
index idx_name (name)
);SHOW CREATE TABLE returns the standard MySQL-compatible syntax without partition details:
SHOW CREATE TABLE auto_part_tbl;| auto_part_tbl | CREATE TABLE `auto_part_tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bid` int(11) DEFAULT NULL,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_name` (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8 |SHOW FULL CREATE TABLE returns the complete partition definition:
SHOW FULL CREATE TABLE auto_part_tbl;| auto_part_tbl | CREATE PARTITION TABLE `auto_part_tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bid` int(11) DEFAULT NULL,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
GLOBAL INDEX /* idx_name_$a870 */ `idx_name` (`name`)
PARTITION BY KEY (`name`, `id`) PARTITIONS 16,
LOCAL KEY `_local_idx_name` (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`id`)
PARTITIONS 16
/* tablegroup = `tg108` */ |The output shows:
The primary table (
auto_part_tbl) is partitioned into 16 partitions by KEY onid.The
idx_nameindex is a GSI partitioned into 16 partitions by KEY onname, id.
For manually specified partition keys, see Manually create a partitioned table (AUTO mode).
Supported data types
The table below lists which data types are supported as partition key columns for each partitioning type.
| Data type | HASH | KEY | RANGE | RANGE COLUMNS | LIST | LIST COLUMNS |
|---|---|---|---|---|---|---|
| Integer (TINYINT to BIGINT, signed and unsigned) | Supported | Supported | Supported | Supported | Supported | Supported |
| DECIMAL | Supported (no partition functions; decimal part must be zero for RANGE COLUMNS and LIST COLUMNS) | Supported | Not supported | Supported (decimal part must be zero) | Not supported | Supported (decimal part must be zero) |
| DATE | Supported (partition functions supported) | Supported | Supported (partition function required) | Supported | Supported (partition function required) | Supported |
| DATETIME | Supported (partition functions supported) | Supported | Supported (partition functions supported) | Supported | Supported (partition functions supported) | Supported |
| TIMESTAMP | Supported (partition functions supported) | Supported | Not supported | Not supported | Not supported | Not supported |
| CHAR | Supported (no partition functions) | Supported | Not supported | Supported | Not supported | Supported |
| VARCHAR | Supported (no partition functions) | Supported | Not supported | Supported | Not supported | Supported |
| BINARY | Supported (no partition functions) | Supported | Not supported | Not supported | Not supported | Not supported |
| VARBINARY | Supported (no partition functions) | Supported | Not supported | Not supported | Not supported | Not supported |
Data routing behavior
Effect of data type on routing
The partition key data type determines the hashing or comparison algorithm. Two tables partitioned on the same value but with different column types (e.g., INT vs BIGINT) route that value to different partitions:
EXPLAIN SELECT * FROM tbl_int WHERE a = 12345678;
-- LogicalView(tables="tbl_int[p260]", ...)
EXPLAIN SELECT * FROM tbl_bigint WHERE a = 12345678;
-- LogicalView(tables="tbl_bigint[p477]", ...)Effect of character set and collation on routing
The collation of a string partition key column determines whether routing is case-sensitive:
Case-sensitive collation (e.g.,
utf8_bin):'AbcD'and'abcd'route to different partitions.Case-insensitive collation (e.g.,
utf8_general_ci):'AbcD'and'abcd'route to the same partition.
By default, string partition key columns use utf8_general_ci (case-insensitive).
Example: Case-sensitive routing
-- tbl_varchar_cs uses utf8_bin
EXPLAIN SELECT a FROM tbl_varchar_cs WHERE a IN ('AbcD');
-- LogicalView(tables="tbl_varchar_cs[p29]", ...)
EXPLAIN SELECT a FROM tbl_varchar_cs WHERE a IN ('abcd');
-- LogicalView(tables="tbl_varchar_cs[p11]", ...) -- different partitionExample: Case-insensitive routing
-- tbl_varchar_ci uses utf8_general_ci
EXPLAIN SELECT a FROM tbl_varchar_ci WHERE a IN ('AbcD');
-- LogicalView(tables="tbl_varchar_ci[p4]", ...)
EXPLAIN SELECT a FROM tbl_varchar_ci WHERE a IN ('abcd');
-- LogicalView(tables="tbl_varchar_ci[p4]", ...) -- same partitionChanging the character set or collation of a partition key column triggers a full data redistribution across partitions. Plan this change carefully.
Value truncation
When a partition key value in a query or DML statement exceeds the valid range of the column's data type, PolarDB-X truncates it to the boundary value and routes based on the truncated value.
For a SMALLINT column (range: –32,768 to 32,767):
INSERT INTO tbl_smallint VALUES (12345678), (-12345678);
-- Stored as 32767 and -32768
SELECT * FROM tbl_smallint WHERE a = 12345678;
-- Routes to the same partition as WHERE a = 32767Data type conversion
When a query constant's type differs from the partition key column type, PolarDB-X attempts implicit conversion before routing:
DQL — if conversion fails, the partition key condition is ignored and all partitions are scanned.
DML (
INSERT,REPLACE) — if conversion fails, the statement is rejected with an error.DDL (
CREATE TABLE,ALTER TABLE) — type conversion is not supported; the statement is rejected.
PolarDB-X vs MySQL differences
| Feature | MySQL | PolarDB-X |
|---|---|---|
| Partition key must include primary key | Required | Not required |
| KEY partitioning routing | Modulo by partition count | Consistent hashing (MurmurHash3) |
| HASH partitioning routing | Modulo by partition count | Consistent hashing (MurmurHash3) |
| Multi-column HASH partition key | Not supported | Supported (extended syntax) |
| LINEAR HASH | Supported | Not supported |
HASH(col) vs KEY(col) routing (single-column) | Different algorithms | Same algorithm |
| Partition functions | Any expression in PARTITION BY HASH(expr(col)) | Limited to specific functions (see Partition functions) |
| KEY partitioning column types | All types | Integer, date/time, and string types only |
| Supported character sets | All common character sets | utf8, utf8mb4, gbk |
| Level-2 partitions (subpartitions) | Supported | Supported |
What's next
CREATE DATABASE — create a logical database in AUTO mode
Manually create a partitioned table (AUTO mode) — step-by-step guide with partition design recommendations
ALTER TABLEGROUP — split hot partitions, merge partitions, or migrate partition data