All Products
Search
Document Center

PolarDB:CREATE TABLE (AUTO mode)

Last Updated:Mar 28, 2026

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 with mode='auto'. Run SHOW CREATE DATABASE db_name to 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

TermDefinition
Partition keyOne or more columns used to horizontally split a table across partitions
Partition key columnA single column that is part of a partition key
Single-column partition keyA partition key with exactly one column
Vector partition keyA partition key with two or more columns
Prefix partition key columnIn a vector partition key of N columns, the first K columns (1 ≤ K ≤ N)
Partition functionA function applied to a partition key column before routing. See Partition functions
Partition pruningQuery optimization that skips partitions not matching the WHERE condition
Hot partition splittingSplitting a hot partition into multiple partitions using another column in a vector partition key
Physical partitionA partition stored on a data node; corresponds to one physical table shard
Logical partitionA virtual partition that maps to one or more physical partitions (level-1 partition in a level-2 setup)

Choose a partitioning type

GoalRecommended type
Distribute writes evenly with no range semanticsKEY (default) or HASH
Partition by date or time rangesRANGE with a partition function (e.g., YEAR, TO_DAYS)
Partition by discrete categorical valuesLIST or LIST COLUMNS
Partition by time ranges with multi-column keysRANGE 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 aboveLevel-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_options

And partition_options is:

partition_columns_definition
[subpartition_columns_definition]
[subpartition_specs_definition]   -- templated level-2 partitions
partition_specs_definition

Partition 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 n

Partition 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

ParameterDescription
CHARSET / CHARACTER SETDefault character set for table columns. Supported values: utf8, utf8mb4, gbk
COLLATEDefault 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
TABLEGROUPTable 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
LOCALITYData 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

  • SUBSTR and SUBSTRING require 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 partitioningHASH partitioning
SyntaxPARTITION BY KEY(c1, ..., cn)PARTITION BY HASH(c1) or PARTITION BY HASH(c1, ..., cn)
Single-column keySupportedSupported
Vector partition keySupported (routes by first K columns; other columns available for hot partition splitting)Supported (routes by all columns simultaneously; hot partition splitting not available)
Partition functionsNot supportedSupported for single-column keys
Default typeYes — KEY is the defaultNo

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 COLUMNSRANGE
SyntaxPARTITION BY RANGE COLUMNS(c1, ..., cn)PARTITION BY RANGE(expr(c1))
Vector partition keySupportedNot supported
Partition functionsNot supportedSupported
TIMESTAMP columnsNot supported as partition keyNot supported directly; use UNIX_TIMESTAMP()
String columnsSupportedNot supported
Hot partition splittingSupportedNot supported
Routing algorithmBinary searchBinary 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)
);
Important

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)
);
Important

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

  • NULL cannot be used as a range boundary.

  • If a query specifies NULL for 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 COLUMNSLIST
SyntaxPARTITION BY LIST COLUMNS(c1, ..., cn)PARTITION BY LIST(expr(c1))
Vector partition keySupportedNot supported
Partition functionsNot supportedSupported
TIMESTAMP columnsNot supportedNot supported directly
String columnsSupportedNot supported
DEFAULT partitionSupportedSupported
Hot partition splittingNot supportedNot 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'))
);
Important

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)
);
Important

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_HASHKEYHASH
Single-column keyNot supportedSupportedSupported
Vector partition keySupportedSupportedSupported
Partition functions on vector key columnsSupported (e.g., RIGHT(c1,4))Not supportedNot supported
Partition pruning on any key columnSupported — each column routes independentlySupported on prefix columns onlySupported on all columns together only
Hot partition splittingNot supportedSupportedNot 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 INSERT or REPLACE where the partition key columns in a row route to different partitions is rejected.

    • An UPDATE or UPSERT that 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' becomes 34). This ensures that c1 = 1000034 and c2 = 34 route 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_HASH syntax, 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 n before the partition list.

  • Non-templated: each level-1 partition can have a different number of subpartitions. Defined by specifying SUBPARTITIONS n inside each PARTITION clause.

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 on id.

  • The idx_name index is a GSI partitioned into 16 partitions by KEY on name, 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 typeHASHKEYRANGERANGE COLUMNSLISTLIST COLUMNS
Integer (TINYINT to BIGINT, signed and unsigned)SupportedSupportedSupportedSupportedSupportedSupported
DECIMALSupported (no partition functions; decimal part must be zero for RANGE COLUMNS and LIST COLUMNS)SupportedNot supportedSupported (decimal part must be zero)Not supportedSupported (decimal part must be zero)
DATESupported (partition functions supported)SupportedSupported (partition function required)SupportedSupported (partition function required)Supported
DATETIMESupported (partition functions supported)SupportedSupported (partition functions supported)SupportedSupported (partition functions supported)Supported
TIMESTAMPSupported (partition functions supported)SupportedNot supportedNot supportedNot supportedNot supported
CHARSupported (no partition functions)SupportedNot supportedSupportedNot supportedSupported
VARCHARSupported (no partition functions)SupportedNot supportedSupportedNot supportedSupported
BINARYSupported (no partition functions)SupportedNot supportedNot supportedNot supportedNot supported
VARBINARYSupported (no partition functions)SupportedNot supportedNot supportedNot supportedNot 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 partition

Example: 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 partition
Important

Changing 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 = 32767

Data 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

FeatureMySQLPolarDB-X
Partition key must include primary keyRequiredNot required
KEY partitioning routingModulo by partition countConsistent hashing (MurmurHash3)
HASH partitioning routingModulo by partition countConsistent hashing (MurmurHash3)
Multi-column HASH partition keyNot supportedSupported (extended syntax)
LINEAR HASHSupportedNot supported
HASH(col) vs KEY(col) routing (single-column)Different algorithmsSame algorithm
Partition functionsAny expression in PARTITION BY HASH(expr(col))Limited to specific functions (see Partition functions)
KEY partitioning column typesAll typesInteger, date/time, and string types only
Supported character setsAll common character setsutf8, utf8mb4, gbk
Level-2 partitions (subpartitions)SupportedSupported

What's next