Este tópico explica a sintaxe DDL, as cláusulas e os parâmetros para criar tabelas particionadas em bancos de dados do PolarDB-X no modo AUTO.
Observações
-
Antes de usar a sintaxe para criar tabelas particionadas, **certifique-se de que o banco de dados lógico atual esteja no modo de partição automática (
mode='auto')**. Essa sintaxe não é suportada em outros modos. Execute o comandoSHOW CREATE DATABASE db_namepara verificar o modo do banco de dados lógico atual. Exemplo:CREATE DATABASE part_db mode='auto'; Query OK, 1 row affected (4.29 sec) SHOW CREATE DATABASE part_db; +----------+-----------------------------------------------+ | DATABASE | CREATE DATABASE | +----------+-----------------------------------------------+ | part_db | CREATE DATABASE `part_db` /* MODE = 'auto' */ | +----------+-----------------------------------------------+ 1 row in set (0.18 sec)Para obter detalhes sobre a sintaxe
CREATE DATABASE, consulte CREATE DATABASE. Se a chave primária de uma tabela particionada não incluir a chave de partição e não for uma chave primária com incremento automático, garanta a unicidade da chave primária no nível da aplicação.
Para utilizar o recurso de subparticionamento, a versão da instância deve ser 5.4.17-16952556 ou superior.
Sintaxe
CREATE [PARTITION] TABLE [IF NOT EXISTS] tbl_name
(create_definition, ...)
[table_options]
[table_partition_definition]
[local_partition_definition]
create_definition:
col_name column_definition
| mysql_create_definition
| [UNIQUE] GLOBAL INDEX index_name [index_type] (index_sharding_col_name,...)
[global_secondary_index_option]
[index_option] ...
index_sharding_col_name:
col_name [(length)] [ASC | DESC]
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
index_type:
USING {BTREE | HASH}
# Global secondary index options
global_secondary_index_option:
[COVERING (col_name,...)]
[partition_options]
[VISIBLE|INVISIBLE]
table_options:
table_option [[,] table_option] ...
table_option: {
# Specify a table group
TABLEGROUP [=] value,...,}
# Partitioned table type definition
table_partition_definition:
single
| broadcast
| partition_options
# Partition definition
partition_options:
partition_columns_definition
[subpartition_columns_definition]
[subpartition_specs_definition] /* Defines templated subpartitions. */
partition_specs_definition
# Partition key definition
partition_columns_definition:
PARTITION BY
HASH({column_name | partition_func(column_name)}) partitions_count
| KEY(column_list) partitions_count
| 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_count
# Subpartition key definition
subpartition_columns_definition:
SUBPARTITION BY
HASH({column_name | partition_func(column_name)}) subpartitions_count
| KEY(column_list) subpartitions_count
| 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_count
column_expr_list:
{column_name | partition_func(column_name)},{column_name | partition_func(column_name)}[,{column_name | partition_func(column_name)},...]
partitions_count:
PARTITIONS partition_count
subpartitions_count:
SUBPARTITIONS partition_count
# Partitioning functions
partition_func:
YEAR
| TO_DAYS
| TO_MONTHS
| TO_WEEKS
| TO_SECOND
| UNIX_TIMESTAMP
| MONTH
| DAYOFWEEK
| DAYOFMONTH
| DAYOFYEAR
| SUBSTR
| SUBSTRING
| RIGHT
| LEFT
# Partition specification
partition_specs_definition:
hash_partition_list
| range_partition_list
| list_partition_list
# Subpartition specification
subpartition_specs_definition:
hash_subpartition_list
| range_subpartition_list
| list_subpartition_list
# HASH/KEY partition definition
hash_partition_list:
/* For HASH partitioning, individual partition definitions are optional. */
| ( hash_partition [, hash_partition, ...] )
hash_partition:
PARTITION partition_name [partition_spec_options] /* For partitioned tables that have no subpartitions or use templated subpartitions. */
| PARTITION partition_name subpartitions_count [subpartition_specs_definition] /* Defines non-templated subpartitions within a partition. */
# HASH/KEY subpartition definition
hash_subpartition_list:
| empty
| ( hash_subpartition [, hash_subpartition, ...] )
hash_subpartition:
SUBPARTITION subpartition_name [partition_spec_options]
# RANGE/RANGE COLUMNS partition definition
range_partition_list:
( range_partition [, range_partition, ... ] )
range_partition:
PARTITION partition_name VALUES LESS THAN (range_bound_value) [partition_spec_options] /* For partitioned tables that have no subpartitions or use templated subpartitions. */
| PARTITION partition_name VALUES LESS THAN (range_bound_value) [[subpartitions_count] [subpartition_specs_definition]] /* Defines non-templated subpartitions within a partition. */
# RANGE/RANGE COLUMNS subpartition definition
range_subpartition_list:
( range_subpartition [, range_subpartition, ... ] )
range_subpartition:
SUBPARTITION subpartition_name VALUES LESS THAN (range_bound_value) [partition_spec_options]
range_bound_value:
maxvalue /* Defines a MAXVALUE partition for RANGE partitioning. */
| expr /* Boundary value for a single partition key */
| value_list /* Boundary values for multiple partition keys */
# LIST/LIST COLUMNS partition definition
list_partition_list:
(list_partition [, list_partition ...])
list_partition:
PARTITION partition_name VALUES IN (list_bound_value) [partition_spec_options] /* For partitioned tables that have no subpartitions or use templated subpartitions. */
| PARTITION partition_name VALUES IN (list_bound_value) [[subpartitions_count] [subpartition_specs_definition]] /* Defines non-templated subpartitions within a partition. */
# LIST/LIST COLUMNS subpartition definition
list_subpartition_list:
(list_subpartition [, list_subpartition ...])
list_subpartition:
SUBPARTITION subpartition_name VALUES IN (list_bound_value) [partition_spec_options]
list_bound_value:
default /* Defines a DEFAULT partition for LIST partitioning. */
| value_set
value_set:
value_list /* Set of values for a single partition key */
| (value_list) [, (value_list), ...] /* Sets of values for multiple partition keys */
value_list:
value [, value, ...]
partition_spec_options:
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string']
[LOCALITY [=] locality_option]
table_option:
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string']
[{CHARSET | CHARACTER SET} [=] charset]
[COLLATE [=] collation]
[TABLEGROUP [=] table_group_id]
[LOCALITY [=] locality_option]
locality_option:
'dn=storage_inst_id_list'
storage_inst_id_list:
storage_inst_id[,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 pivotdate_func]
[DISABLE SCHEDULE]
pivotdate_func:
NOW()
| DATE_ADD(...)
| DATE_SUB(...)
A sintaxe DDL do PolarDB-X baseia-se no MySQL. A sintaxe acima destaca as principais diferenças. Para a sintaxe completa, consulte a documentação do MySQL.
Glossário
Chave de partição: Uma ou mais colunas em uma tabela particionada usadas para o particionamento horizontal.
Coluna de partição: Coluna utilizada para roteamento e cálculo de partições em uma tabela particionada horizontalmente. Geralmente faz parte de uma chave de partição.
Chave de partição vetorial: Chave de partição composta por uma ou mais colunas de partição.
Chave de partição de coluna única: Chave de partição formada por apenas uma coluna de partição.
Coluna de partição de prefixo: Em uma chave de partição vetorial com N colunas (N > 1), o prefixo consiste nas primeiras K colunas, onde 1 <= K < N.
Função de partição: Função que recebe uma coluna de partição como entrada e fornece o valor para cálculos de roteamento.
Pruning de partição: Técnica de otimização de consultas que evita a varredura de partições desnecessárias com base nas definições de partição e nas condições da consulta.
Divisão de hot spot: Técnica de balanceamento de carga que divide uma partição quente usando a coluna de partição subsequente. Essa divisão ocorre quando as colunas de partição de prefixo de uma chave vetorial apresentam pontos de acesso frequentes ou distribuição desigual de dados.
Partição física: Partição com mapeamento um para um para uma subtabela física em um nó DN.
Partição lógica: Partição virtual que se mapeia para uma ou mais partições físicas. Por exemplo, em uma tabela criada com subparticionamento, as partições de primeiro nível são partições lógicas.
Parâmetros
|
Parâmetro |
Descrição |
|
|
Define o conjunto de caracteres padrão para as colunas da tabela. Os seguintes conjuntos de caracteres são suportados:
|
|
|
Define a collation padrão para as colunas da tabela. As seguintes collations são suportadas:
|
|
|
Especifica o grupo de tabelas para a tabela particionada. Se omitido, o sistema localiza ou cria automaticamente um grupo de tabelas compatível com o método de particionamento da tabela. |
|
|
Indica os nós de dados que armazenam a tabela particionada. |
Tabelas únicas
No PolarDB-X, crie tabelas não particionadas usando a palavra-chave SINGLE. Exemplo:
CREATE TABLE single_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) SINGLE;
Tabelas de broadcast
No PolarDB-X, crie tabelas de broadcast especificando a palavra-chave BROADCAST. Uma tabela de broadcast contém uma cópia idêntica de seus dados em todos os nós de dados. Exemplo:
CREATE TABLE broadcast_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) BROADCAST;
Tabela particionada
Tipos de partição
O PolarDB-X permite criar tabelas particionadas para atender aos requisitos de negócio através da especificação de uma cláusula de partição. O PolarDB-X suporta os quatro tipos de particionamento a seguir:
Particionamento Hash: Esta estratégia roteia dados aplicando um algoritmo de hash consistente interno ao valor de uma coluna de partição ou expressão de função de partição. O particionamento Hash subdivide-se em duas estratégias, Particionamento Key e Particionamento Hash, dependendo se uma expressão de função de partição ou múltiplas colunas podem ser usadas como chave de partição.
Particionamento Range: Roteia dados comparando o valor de uma coluna de partição ou expressão de função contra intervalos predefinidos. Subdivide-se em Particionamento Range Columns e Particionamento Range, conforme a possibilidade de uso de expressões de função ou múltiplas colunas como chave.
Particionamento List: Semelhante ao particionamento Range, roteia dados verificando se o valor de uma coluna ou expressão está contido em uma lista predefinida de valores. Divide-se em Particionamento List Columns e Particionamento List, baseado no uso de múltiplas colunas como chave.
CoHash: Estratégia estendida de particionamento hash do PolarDB-X, projetada para cenários específicos e comuns. Permite o particionamento horizontal de uma tabela com base em múltiplas colunas de partição correlacionadas.
Tipo Hash
No PolarDB-X, existem dois tipos de particionamento baseado em hash: particionamento hash e particionamento key. Ambos fazem parte da sintaxe padrão de particionamento do MySQL nativo. Para habilitar recursos flexíveis de gerenciamento de partições — como divisão, mesclagem e migração — e suportar a divisão de hot spots para chaves de partição vetoriais, o PolarDB-X redefine o roteamento para os particionamentos hash e key; embora mantenha compatibilidade sintática com a sintaxe CREATE TABLE do MySQL, sua implementação subjacente de partition routing difere da do MySQL. A tabela a seguir descreve as diferenças entre o particionamento key e o particionamento hash:
Tabela 1. Comparação das estratégias de particionamento key e hash
|
Estratégia de particionamento |
Suporte a chave de partição |
Suporte a função de partição |
Exemplo de sintaxe |
Recursos e limitações |
Roteamento (consulta pontual) |
|
Key (estratégia de particionamento padrão) |
chave de partição de coluna única |
Não |
PARTITION BY KEY(c1) |
|
|
|
chave de partição vetorial |
Não |
PARTITION BY KEY(c1, c2, ..., cn) |
|
|
|
|
Hash |
chave de partição de coluna única |
Não |
PARTITION BY HASH(c1) |
|
|
|
Sim |
PARTITION BY HASH(YEAR(c1)) |
|
|||
|
chave de partição vetorial |
Não |
PARTITION BY HASH(c1, c2, ..., cn) |
|
|
Exemplo 1-1: Partição Key
O particionamento Key também é o método de particionamento padrão no PolarDB-X. Este método suporta chaves de partição vetoriais. Por exemplo, a instrução a seguir cria uma tabela particionada pelo nome do usuário (name) e ID do usuário (id) em oito partições:
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;
Para uma partitioned table que usa uma KEY partition com uma vector partition key, o routing depende, por padrão, apenas da primeira partition column (name). Portanto, o partition pruning é acionado quando a WHERE clause contém uma equality condition para esta primeira partition column. Exemplo:
## This query triggers partition pruning and scans only a single partition.
SELECT id from key_tbl where name='Jack';
Caso a primeira partition column, name, cause data imbalance ou um data hotspot, realize uma partition split usando a próxima partition column, como id. Para mais detalhes, consulte Modify a table group level partition (AUTO mode).
Se uma chave de partição vetorial com N colunas usar suas primeiras K colunas para roteamento (1 ≤ K ≤ N), incluir condições nas colunas de partição de prefixo (as primeiras K colunas) na cláusula WHERE habilita o pruning de partição.
Exemplo 1-2: Particionamento Hash
Para usar um ID de usuário como chave de partição para particionamento horizontal, crie a tabela usando particionamento hash e especifique 8 partições:
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;
O particionamento Hash suporta expressões de função de partição, como YEAR() e TO_DAYS(), para converter valores de tipos de tempo em tipos inteiros. Por exemplo, para particionar uma tabela pela coluna birthday em 8 partições hash, use a seguinte instrução:
CREATE TABLE hash_tbl_todays(
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;
Atualmente, o PolarDB-X suporta as seguintes funções de partição:
YEAR
MONTH
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
TO_DAYS
TO_MONTHS
TO_WEEKS
TO_SECONDS
UNIX_TIMESTAMP
SUBSTR/SUBSTRING
Para as funções SUBSTR/SUBSTRING, a chave de partição deve ser do tipo string; para todas as outras funções de partição, deve ser do tipo tempo (como DATE, DATETIME ou TIMESTAMP).
Exemplo 1-3: Expansão de partição Hash
O PolarDB-X estende a sintaxe de particionamento hash para suportar uma chave de partição vetorial. Ao contrário da sintaxe padrão de particionamento do MySQL nativo, o PolarDB-X permite particionar por múltiplas colunas com o método HASH. Use a seguinte instrução:
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;
Diferentemente do particionamento key, o particionamento hash usa uma chave de partição vetorial, onde todas as colunas de partição contribuem tanto para os cálculos de hash quanto para os de roteamento. Portanto, para habilitar o pruning de partição, a cláusula WHERE de uma consulta SQL deve especificar condições de igualdade para todas as colunas de partição. Por exemplo, SQL1 pode acionar o pruning de partição na tabela hash_tbl2, mas SQL2 não:
##SQL1 (This query triggers partition pruning, scanning only a single partition)
SELECT id from hash_tbl2 where name='Jack' and birthday='1990-11-11';
##SQL2 (This query does not trigger partition pruning, resulting in a full partition scan)
SELECT id from hash_tbl2 where name='Jack';
Como o hash partitioning usa toda a partition key para calcular o hash value antecipadamente, ele teoricamente distribui os dados de forma mais uniforme do que o key partitioning usando uma vector partitioning key. No entanto, não pode suportar hotspot splitting, pois não há column s subsequentes disponíveis para dividir uma partição quente.
Limitações
-
Limitações de tipo de dados
Tipos inteiros:
BIGINT,BIGINT UNSIGNED,INT,INT UNSIGNED,MEDIUMINT,MEDIUMINT UNSIGNED,SMALLINT,SMALLINT UNSIGNED,TINYINTeTINYINT UNSIGNED.Tipos de tempo:
DATETIME,DATEeTIMESTAMP.Tipos de string:
CHAReVARCHAR.
-
Limitações de sintaxe
Ao usar uma função de partição com uma chave de partição de coluna única para uma partição hash, a chave deve ser do tipo tempo.
Uma chave de partição vetorial para uma partição hash não suporta funções de partição ou divisão de hot spot.
Por padrão, o número máximo de partições é 8.192.
Por padrão, o número máximo de colunas de partição é 5.
Uniformidade de Dados
O algoritmo de hash consistente interno para particionamento key e hash é o MurmurHash3, um algoritmo de alto desempenho com baixa probabilidade de colisão.
Com o MurmurHash3, a distribuição de dados para particionamento key e hash geralmente se torna equilibrada apenas quando o número de valores distintos de chave de partição (N) excede 3.000. Quanto maior o valor de N, mais equilibrada será a distribuição dos dados.
Tipo Range
No PolarDB-X, existem dois tipos de particionamento range: partição range e partição range columns. Ambos fazem parte da sintaxe padrão de particionamento do MySQL nativo. A tabela a seguir compara esses dois tipos de partição.
Tabela 2. Comparação das estratégias de particionamento Range Columns e Range
|
Estratégia de particionamento |
Suporte a chave de partição |
Suporte a função de partição |
Exemplo de sintaxe |
Recursos e limitações |
Roteamento (consulta pontual) |
|
Range Columns |
chaves de partição de coluna única e vetorial |
Não |
PARTITION BY RANGE COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES LESS THAN (1,10,...,1000), PARTITION p2 VALUES LESS THAN (2,20,...,2000) ...) |
Suporta divisão de hot spot. Por exemplo, se a coluna |
|
|
Range |
chave de partição de coluna única |
Sim |
PARTITION BY RANGE(YEAR(c1)) ( PARTITION p1 VALUES LESS THAN (2019), PARTITION p2 VALUES LESS THAN (2021) ...) |
|
|
Exemplo 2-1: Particionamento Range columns
O particionamento Range columns suporta uma chave de partição vetorial, mas não uma função de partição. Por exemplo, para particionar uma tabela por ID do pedido e data do pedido, use a seguinte sintaxe CREATE TABLE:
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)
);
O particionamento range columns não suporta tipos de dados sensíveis a fuso horário, como TIMESTAMP e TIME, como chave de partição.
Exemplo 2-2: Particionamento range
O particionamento Range suporta apenas uma chave de partição de coluna única. No entanto, para uma coluna de partição datetime, utilize funções de partição como YEAR, TO_DAYS, TO_SECONDS ou MONTH para converter seus valores em inteiros.
O particionamento Range não suporta diretamente um tipo string como coluna de partição.
Por exemplo, para criar partições trimestrais na coluna order_time usando particionamento range, use a seguinte sintaxe:
CREATE TABLE orders_todays(
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)
);
O particionamento Range suporta apenas uma única coluna do tipo inteiro como chave de partição.
Limites
-
Restrições de tipo de dados
Tipos inteiros:
BIGINT,BIGINT UNSIGNED,INT,INT UNSIGNED,MEDIUMINT,MEDIUMINT UNSIGNED,SMALLINT,SMALLINT UNSIGNED,TINYINTeTINYINT UNSIGNED.Tipos de data e hora:
DATETIMEeDATE.Tipos de string:
CHAReVARCHAR.
-
Restrições de sintaxe
Os particionamentos
RANGE COLUMNSeRANGEnão suportam o uso de um valorNULLcomo valor limite.O particionamento
RANGE COLUMNSnão suporta o tipo de dadosTIMESTAMP.O particionamento
RANGEsuporta apenas tipos inteiros. Se a chave de partição usar o tipoTIMESTAMP, utilize a funçãoUNIX_TIMESTAMPpara garantir a consistência do fuso horário.O particionamento
RANGEnão suporta divisão de hot spot.Durante consultas, valores
NULLsão tratados como o valor mínimo para roteamento de partição.Por padrão, o número máximo de partições é 8.192.
Por padrão, o número máximo de colunas de partição é 5.
Tipo List
Semelhante ao range type, o PolarDB-X subdivide a list partitioning policy em dois tipos: list partitioning e list columns partitioning. Ambos usam a sintaxe padrão de particionamento do MySQL nativo. Além disso, o PolarDB-X suporta uma default partition tanto para list partitioning quanto para list columns partitioning. Esta tabela compara os dois tipos:
Tabela 3. Comparação das estratégias de particionamento List Columns e List
|
Estratégia de particionamento |
Suporte a chave de partição |
Suporte a função de partição |
Exemplo de sintaxe |
Recursos e limitações |
Roteamento (consulta pontual) |
|
List Columns |
chave de partição de coluna única e vetorial |
Não |
PARTITION BY LIST COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES IN ((1,10,...,1000),(2,20,...,2000) ), PARTITION p2 VALUES IN ((3,30,...,3000),(3,30,...,3000) ), ...) |
Não suporta divisão de hot spot. |
|
|
List |
chave de partição de coluna única |
Sim |
PARTITION BY LIST(YEAR(c1)) ( PARTITION p1 VALUES IN (2018,2019), PARTITION p2 VALUES IN (2020,2021) ...) |
Não suporta divisão de hot spot. |
Exemplo 3-1: Particionamento List columns
O list columns partitioning suporta vector partition keys. Por exemplo, o list columns partitioning permite particionar pedidos por país e cidade. A table creation syntax é a seguinte:
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'))
);
O List Columns partitioning atualmente não suporta tipos de dados com informações de fuso horário, como TIMESTAMP e TIME, como partition key.
Exemplo 3-2: Particionamento list
Embora o list partitioning suporte apenas uma single-column partition key, para uma partition column do time-type, utilize partition function expressions como YEAR, MONTH, DAYOFMONTH, TO_DAYS e TO_SECONDS para converter seus valores em um integer type.
Por exemplo, para criar uma list partition baseada no ano da coluna order_time, use a seguinte sintaxe create table:
CREATE TABLE orders_years(
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)
);
O particionamento suporta apenas o integer type como partition key. O string type não é suportado como partition column.
Exemplo 3-3: Partições List columns e list com uma partição padrão
O PolarDB-X suporta a criação de list columns partitions e list partitions que incluem uma default partition, para onde são roteados os dados não definidos nas regular partitions.
Defina no máximo uma partição padrão, que deve ser a última partição.
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')),
PARTITION pd VALUES IN (DEFAULT)
);
CREATE TABLE orders_years(
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)
);
Limites
-
Restrições de tipo de dados
Tipos inteiros: BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT e TINYINT UNSIGNED.
Tipos de tempo: DATETIME e DATE.
Tipos de string: CHAR e VARCHAR.
-
Restrições de sintaxe
O particionamento List Columns não suporta o tipo de dados TIMESTAMP.
O particionamento List suporta apenas tipos inteiros.
Nem o particionamento List Columns nem o particionamento List suportam divisão de hot spot.
Por padrão, o número máximo de partições é 8.192.
Por padrão, o número máximo de colunas de partição é 5.
Tipo CoHash
A política de particionamento CoHash do PolarDB-X é exclusiva do PolarDB-X.
Requisitos de versão
Use a versão 5.4.18-17047709 ou superior.
Casos de uso
Esta estratégia de particionamento é comumente usada nos seguintes cenários de negócio:
Se uma tabela possui colunas correlacionadas, como c1 e c2, cujos últimos quatro caracteres são sempre idênticos, particione-a horizontalmente em ambas as colunas para rotear consultas SQL com condição de igualdade em qualquer uma das colunas para uma única partição.
Portanto, esta estratégia exige que os valores permaneçam consistentes em várias colunas de partição na mesma tabela particionada.
Exemplo 4-1: Definir co-localização com funções de partição independentes
Suponha que sua aplicação tenha uma tabela orders onde as colunas order_id e buyer_id compartilham os mesmos seis últimos dígitos em cada linha. Para particionar esta tabela por esses dígitos compartilhados e garantir que uma consulta de igualdade em qualquer coluna seja roteada para a mesma partição, use a seguinte sintaxe:
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) /* The last 6 characters of order_id */,
RIGHT(`buyer_id`,6) /* The last 6 characters of buyer_id */
)
PARTITIONS 8;
Exemplo 4-2: Usando o açúcar sintático Range_Hash para migração de usuários da 1.0 para 2.0
Para uma migração da 1.0 para 2.0, considere uma tabela orders fragmentada por banco de dados e tabela usando range_hash, definida como: DBPARTIITION BY RANGE_HASH(. Sua tabela particionada correspondente no banco de dados 2.0 AUTO é definida da seguinte forma:
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;
O PolarDB-X converte automaticamente a sintaxe RANGE_HASH em uma definição de partição CO_HASH. Por exemplo, RANGE_HASH(order_id, buyer_Id, 6) torna-se a seguinte definição CO_HASH:
CREATE TABLE orders(
id bigint not null auto_increment,
buyer_id bigint,
order_id bigint,
...
primary key(id)
)
PARTITION BY CO_HASH(
RIGHT(`order_id`,6) /* Uses the last 6 characters of order_id */,
RIGHT(`buyer_id`,6) /* Uses the last 6 characters of buyer_id */
)
PARTITIONS 8;
Principais diferenças em relação ao particionamento hash/key
Como as estratégias de particionamento CoHash e hash/key são semelhantes, esta seção delineia suas principais semelhanças e diferenças de uso.
|
Principais diferenças |
CO_HASH |
KEY |
HASH |
|
Exemplo de sintaxe |
PARTITION BY CO_HASH(c1, c2) PARTITIONS 8 |
PARTITION BY KEY(c1, c2) PARTITIONS 8 |
PARTITION BY HASH(c1, c2) PARTITIONS 8 |
|
Chave de partição de coluna única |
Não suportado |
Suportado |
Suportado |
|
Chave de partição vetorial |
Suportado |
Suportado |
Suportado |
|
Uso de funções de partição em colunas de partição vetorial |
Suportado. Exemplo: PARTITION BY CO_HASH( Extracts the last 4 characters of c1 RIGHT(c1, 4), / Extracts the last 4 characters of c2 / RIGHT(c2, 4) ) PARTITIONS 8 |
Não suportado |
Não suportado |
|
Relação entre colunas de partição |
Uma relação de co-localização. A aplicação deve fornecer e manter essa relação entre os valores das colunas de partição. Exemplo:
|
Semelhante à relação de prefixo de um índice composto. |
Semelhante à relação de prefixo de um índice composto. |
|
Pruning de partição para consultas de igualdade de coluna de prefixo |
Suportado. Exemplo:
|
Suportado. Exemplo:
|
Não suportado. O pruning de partição requer condições de igualdade em todas as colunas de partição. Exemplo:
|
|
Pruning de partição para consultas de igualdade de coluna não-prefixo |
Suportado. Condições de igualdade em qualquer coluna de partição podem acionar independentemente o pruning de partição. Exemplo:
|
Não suportado. Condições de igualdade em colunas de partição não-prefixo exigem uma varredura completa de partição. Exemplo:
|
Não suportado. Condições de igualdade em colunas de partição não-prefixo exigem uma varredura completa de partição. Exemplo:
|
|
Consultas de intervalo |
Não suportado. Resulta em uma varredura completa de partição. |
Não suportado. Resulta em uma varredura completa de partição. |
Não suportado. Resulta em uma varredura completa de partição. |
|
Descrição de roteamento (consulta pontual) |
|
Veja a comparação de particionamento KEY e HASH nas linhas acima. |
Veja a comparação de particionamento KEY e HASH nas linhas acima. |
|
Divisão de hot spot |
Não suportado. Não é possível dividir ainda mais uma partição com base em um valor específico de hot spot, como |
Suportado |
Não suportado |
|
Gerenciamento de partição (ex.: divisão, mesclagem e migração de partição) |
Suportado |
Suportado |
Suportado |
|
Subparticionamento |
Suportado |
Suportado |
Suportado |
Considerações
-
Seu serviço deve manter a relação coordenada entre os valores das colunas de partição; o PolarDB-X valida apenas os resultados de roteamento. Ao usar o particionamento
CO_HASH, o PolarDB-X verifica se todos os valores de coluna de partição especificados para uma linha roteiam para o mesmo shard. No entanto, ele não valida se os próprios valores aderem à relação coordenada. Essa imposição é responsabilidade do seu serviço.Por exemplo, suponha que seu serviço exija que os últimos quatro caracteres das colunas c1 e c2 sejam idênticos. Se um valor para c1, como 100234, e um valor para c2, como 1320, ambos rotearem para o shard 0, o PolarDB-X permite a operação
insert (c1,c2) values (100234,1320)porque o roteamento é consistente. Contudo, essa operação viola a regra de negócio, já que os últimos quatro caracteres de c1 (0234) e c2 (1320) não são iguais.
-
Restrições DML na modificação de colunas de partição Como o particionamento CO_HASH correlaciona os valores de múltiplas colunas de partição, o PolarDB-X impõe as seguintes restrições em operações DML que modificam essas colunas para evitar distribuição incorreta de dados:
Para instruções insert e replace, se os valores para diferentes colunas de partição em uma única linha da cláusula
VALUESresultarem em partições diferentes, o PolarDB-X rejeita a operação.Para instruções update e upsert, modifique todas as colunas de partição simultaneamente na cláusula
SET. Por exemplo, se c1 e c2 forem colunas de partição, use uma instrução comoUPDATE t1 SET c1='xx',c2='yy' WHERE id=1. Se os novos valores para diferentes colunas de partição em uma única linha resultarem em partições diferentes, o PolarDB-X rejeita a instrução.Quando CO_HASH é a estratégia de particionamento para um índice secundário global (GSI), o PolarDB-X também rejeita qualquer operação DML na tabela primária que faça com que os valores para diferentes colunas de partição em uma única linha do GSI resultem em partições diferentes.
Tratamento de zeros à esquerda para tipos inteiros. Como as
partition columnsem uma estratégiaCO_HASHsão correlacionadas, frequentemente elas são definidas usando umapartition functioncomoSUBSTR,LEFTouRIGHT. Esse processo pode resultar em zeros à esquerda quando inteiros são truncados. Por exemplo, suponha que sua lógica de negócio exija que os últimos quatro caracteres dec1ec2sejam idênticos. Sec1for1000034, os últimos quatro caracteres são astring'0034'. Para umapartition columndeinteger type, oCO_HASHconverte automaticamente qualquer valor truncado para ointeger typedaquela coluna antes dorouting. Como resultado, oCO_HASHconverte astring'0034'para o inteiro34, calcula ohash valuee roteia a linha. Este processo lida automaticamente com zeros à esquerda.
Limitações de função de partição
RIGHT
LEFT
SUBSTR
Restrições de tipo de dados
tipos inteiros: BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT e TINYINT UNSIGNED
tipo de ponto fixo: DECIMAL (com escala 0)
tipos de tempo: Não suportado
tipos de string: CHAR e VARCHAR
Restrições de sintaxe
Não use funções de partição aninhadas, como
SUBSTR(SUBSTR(c1,-6),-4), em uma coluna de partição.
Ao usar o açúcar sintático
RANGE_HASH, o parâmetro de comprimento não deve ser negativo.-
Todas as colunas de partição devem ter exatamente o mesmo tipo de dados, incluindo as seguintes propriedades:
Conjunto de caracteres e collation
Comprimento e precisão
Por padrão, o número máximo de partições é 8.192.
Por padrão, o número máximo de colunas de partição é 5.
Subpartição
Assim como o MySQL, o PolarDB-X suporta sintaxe de subparticionamento para criar tabelas particionadas com subpartições. O subparticionamento divide ainda mais cada partição com base em uma coluna de partição e estratégia de particionamento especificadas.
Em uma tabela particionada em dois níveis, cada partição de primeiro nível é uma partição lógica que mapeia para um conjunto de partições de segundo nível.
Cada partição de segundo nível é uma partição física que mapeia para um shard de tabela física específico em um nó DN.
Com modelo e sem modelo
As subpartições de segundo nível do PolarDB-X dividem-se em duas categorias principais: com modelo (templated) e sem modelo (non-templated):
subpartição com modelo: O número de subpartições e seus valores limite de partição são os mesmos para cada partição.
subpartição sem modelo: O número de subpartições e seus valores limite podem ser diferentes para cada partição.
Restrições de sintaxe
Por padrão, uma tabela particionada que usa subparticionamento não pode ter mais de 8.192 partições físicas.
Ao usar partições sem modelo, todos os nomes de subpartição devem ser únicos e não podem coincidir com nenhum nome de partição.
Ao usar partições com modelo, todos os nomes de subpartição no modelo devem ser únicos e não podem coincidir com nenhum nome de partição.
Com o subparticionamento, o número total de partições físicas em uma tabela é a contagem total de subpartições em todas as partições. Esse número pode aumentar rapidamente. Portanto, gerencie cuidadosamente o número de partições e subpartições para evitar degradação de desempenho devido ao excesso de particionamento ou erros por exceder o limite total de partições.
Exemplo 5-1: Subpartição com modelo
/*
* This example defines templated subpartitions by using a LIST-KEY composite strategy.
* The table is first partitioned by LIST COLUMNS into three partitions.
* Each partition is then subpartitioned by KEY into four subpartitions, resulting in a total of 12 physical partitions.
*/
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 (('Russian','Moscow')),
PARTITION pd VALUES IN (DEFAULT)
);
Exemplo 5-2: Subpartição sem modelo
/*
* This example uses a LIST-KEY composite strategy to define non-templated subpartitions.
* The table is partitioned by LIST COLUMNS into three first-level partitions, each of which is then subpartitioned by KEY.
* The first-level partitions have 2, 3, and 4 subpartitions, respectively.
* This results in a total of 9 physical partitions (2 + 3 + 4).
*/
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
);
Particionamento automático
Por padrão, o automatic partitioning está desativado para bancos de dados no AUTO mode. Para ativar esse recurso, execute o seguinte comando:
SET GLOBAL AUTO_PARTITION=true;
Com o particionamento automático ativado:
-
Ao criar uma tabela sem especificar uma chave de particionamento, o PolarDB-X particiona a tabela por padrão usando sua chave primária. Se a tabela não tiver chave primária, ele usa a chave primária implícita. Este processo utiliza particionamento KEY, resultando em uma tabela particionada de nível 1.
Por padrão, o número de partições é oito vezes o número de nós lógicos na instância. Por exemplo, se uma instância PolarDB-X for criada com dois nós lógicos, o número padrão de partições será 16.
Além de particionar a tabela principal, o PolarDB-X também particiona todos os seus índices por padrão. A chave de particionamento para um índice consiste nas colunas do índice e nas colunas da chave primária da tabela.
O exemplo a seguir mostra a sintaxe padrão do MySQL para criar uma tabela, onde id é a chave primária e name é a coluna indexada:
CREATE TABLE auto_part_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id),
index idx_name (name)
);
Executar a instrução SHOW CREATE TABLE exibe a sintaxe padrão de criação de tabela do MySQL e oculta automaticamente todas as informações de partição:
show create table auto_part_tbl;
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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 |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
Executar a instrução SHOW FULL CREATE TABLE exibe todas as informações de partição para a tabela principal e suas tabelas de índice:
show full create table auto_part_tbl;
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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
/* table group = `tg108` */ |
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
A saída mostra o seguinte:
Por padrão, a tabela principal
auto_part_tblé particionada pela colunaidusando particionamentoKEYem 16 partições.Por padrão, o índice
idx_namena tabela principal é um índice global que usa as colunasnameeidcomo chave de particionamento e possui 16 partições.
Particionamento manual
Crie uma tabela particionada manualmente especificando uma coluna de partição, função de partição e tipo de partição na instrução CREATE TABLE. Para mais informações sobre tipos de partição, consulte Create a partitioned table manually (AUTO mode).
Tipos de dados
Tabela 4. Tipos de dados suportados para colunas de chave de partição por tipo de particionamento
|
Tipo de dado |
Particionamento Hash |
Particionamento Range |
Particionamento List |
|||||
|
Hash |
Key |
Range |
Range columns |
List |
List columns |
|||
|
Chave de partição de coluna única |
Múltiplas colunas de chave de partição |
|||||||
|
Tipo inteiro |
TINYINT |
|
|
|
|
|
|
|
|
TINYINT UNSIGNED |
|
|
|
|
|
|
|
|
|
SMALLINT |
|
|
|
|
|
|
|
|
|
SMALLINT UNSIGNED |
|
|
|
|
|
|
|
|
|
MEDIUMINT |
|
|
|
|
|
|
|
|
|
MEDIUMINT UNSIGNED |
|
|
|
|
|
|
|
|
|
INT |
|
|
|
|
|
|
|
|
|
INT UNSIGNED |
|
|
|
|
|
|
|
|
|
BIGINT |
|
|
|
|
|
|
|
|
|
BIGINT UNSIGNED |
|
|
|
|
|
|
|
|
|
Tipo de ponto fixo |
DECIMAL |
(Funções de partição não suportadas.) |
|
|
|
|
|
|
|
Tipo de data e hora |
DATE |
|
|
|
|
|
|
|
|
DATETIME |
|
|
|
|
|
|
|
|
|
TIMESTAMP |
|
|
|
|
|
|
|
|
|
Tipo string |
CHAR |
|
|
|
|
|
|
|
|
VARCHAR |
|
|
|
|
|
|
|
|
|
Tipo binário |
BINARY |
|
|
|
|
|
|
|
|
VARBINARY |
|
|
|
|
|
|
|
|
Tipos de dados de chave de partição e roteamento
O roteamento de uma tabela particionada depende diretamente do tipo de dados da chave de partição, especialmente para partições key e hash. Diferentes tipos de dados usam algoritmos de hash ou lógicas de comparação diferentes (como sensibilidade a maiúsculas/minúsculas), o que resulta em comportamentos de roteamento distintos. (Nota: O roteamento de partição no MySQL também é fortemente dependente do tipo.)
Este exemplo mostra duas tabelas, tbl_int e tbl_bigint, ambas com 1.024 partições. A tabela tbl_int usa uma chave de partição int, enquanto tbl_bigint usa uma chave de partição bigint. Embora ambos sejam tipos inteiros, essa diferença faz com que o mesmo valor de consulta (12345678) seja roteado para partições diferentes:
show create table tbl_int;
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_int | CREATE TABLE `tbl_int` (
`a` int(11) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 1024 |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
show create table tbl_bigint;
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_bigint | CREATE TABLE `tbl_bigint` (
`a` bigint(20) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 1024 |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.10 sec)mysql> create table if not exists tbl_bigint(a bigint not null)
-> partition by key(a) partitions 1024;
Query OK, 0 rows affected (28.41 sec)
explain select * from tbl_int where a=12345678;
+---------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+---------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_int[p260]", sql="SELECT `a` FROM `tbl_int` AS `tbl_int` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: c90af636 |
+---------------------------------------------------------------------------------------------------+
4 rows in set (0.45 sec)
explain select * from tbl_bigint where a=12345678;
+------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_bigint[p477]", sql="SELECT `a` FROM `tbl_bigint` AS `tbl_bigint` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 9b2fa47c |
+------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
Sensibilidade a maiúsculas/minúsculas, conjunto de caracteres e collation
O conjunto de caracteres e a collation de uma chave de partição afetam diretamente o algoritmo de roteamento de uma tabela particionada. Por exemplo, eles determinam se o roteamento diferencia maiúsculas de minúsculas. Se a collation de uma tabela for sensível a maiúsculas/minúsculas, o hash e a comparação durante o roteamento também serão. Inversamente, se a collation não diferenciar maiúsculas de minúsculas, essas operações também não diferenciarão. Por padrão, uma chave de partição string usa o conjunto de caracteres utf8 e a collation insensível a maiúsculas/minúsculas utf8_general_ci.
Exemplo 1
Para tornar o roteamento da chave de partição sensível a maiúsculas/minúsculas, defina a collation da tabela para uma collation sensível, como utf8_bin, ao criar a tabela. No exemplo abaixo, a tabela tbl_varchar_cs usa CHARACTER SET utf8 COLLATE utf8_bin. Como resultado, ela roteia as strings 'AbcD' e 'abcd', que diferem apenas em maiúsculas/minúsculas, para partições diferentes:
show create table tbl_varchar_cs;
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_varchar_cs | CREATE TABLE `tbl_varchar_cs` (
`a` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`a`)
PARTITIONS 64 |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.07 sec)
explain select a from tbl_varchar_cs where a in ('AbcD');
+-------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+-------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_cs[p29]", sql="SELECT `a` FROM `tbl_varchar_cs` AS `tbl_varchar_cs` WHERE (`a` IN(?))") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 2c49c244 |
+-------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.11 sec)
explain select a from tbl_varchar_cs where a in ('abcd');
+-------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+-------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_cs[p11]", sql="SELECT `a` FROM `tbl_varchar_cs` AS `tbl_varchar_cs` WHERE (`a` IN(?))") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: 2c49c244 |
+-------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
Exemplo 2
Para tornar o roteamento da chave de partição insensível a maiúsculas/minúsculas, defina a collation da tabela para uma collation insensível, como utf8_general_ci, ao criar a tabela. No exemplo abaixo, a tabela tbl_varchar_ci usa CHARACTER SET utf8 COLLATE utf8_general_ci. Como resultado, ela roteia as strings 'AbcD' e 'abcd' para a mesma partição:
show create table tbl_varchar_ci;
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_varchar_ci | CREATE TABLE `tbl_varchar_ci` (
`a` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`a`)
PARTITIONS 64 |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
explain select a from tbl_varchar_ci where a in ('AbcD');
+------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_ci[p4]", sql="SELECT `a` FROM `tbl_varchar_ci` AS `tbl_varchar_ci` WHERE (`a` IN(?))") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 5c97178e |
+------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.15 sec)
explain select a from tbl_varchar_ci where a in ('abcd');
+------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_ci[p4]", sql="SELECT `a` FROM `tbl_varchar_ci` AS `tbl_varchar_ci` WHERE (`a` IN(?))") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: 5c97178e |
+------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
Alterações no conjunto de caracteres e collation
Como o algoritmo de roteamento de uma tabela particionada é determinado pelo tipo de dados de sua chave de partição, modificar o conjunto de caracteres ou a collation da chave de partição aciona uma redistribuição de todos os dados na tabela. Portanto, tenha cautela ao modificar o tipo de dados de uma chave de partição.
Truncamento e conversão de tipo para colunas de partição
Truncamento de tipo para colunas de partição
Se uma constant expression em uma consulta ou instrução INSERT exceder o intervalo válido para o tipo de dados da partition column, o PolarDB-X primeiro trunca o valor e depois o usa para o routing calculation.
Por exemplo, a tabela tbl_smallint tem uma partition column do tipo smallint, que possui um intervalo válido de -32768 a 32767. Se você tentar inserir um valor fora desse intervalo, como 12345678 ou -12345678, o PolarDB-X primeiro trunca o valor para o valor máximo ou mínimo do tipo smallint (32767 ou -32768, respectivamente). O exemplo a seguir demonstra esse processo.
show create table tbl_smallint;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_smallint | CREATE TABLE `tbl_smallint` (
`a` smallint(6) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 128 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
set sql_mode='';
Query OK, 0 rows affected (0.00 sec)
insert into tbl_smallint values (12345678),(-12345678);
Query OK, 2 rows affected (0.07 sec)
select * from tbl_smallint;
+--------+
| a |
+--------+
| -32768 |
| 32767 |
+--------+
2 rows in set (3.51 sec)
explain select * from tbl_smallint where a=12345678;
+------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_smallint[p117]", sql="SELECT `a` FROM `tbl_smallint` AS `tbl_smallint` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: afb464d5 |
+------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.16 sec)
explain select * from tbl_smallint where a=32767;
+------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_smallint[p117]", sql="SELECT `a` FROM `tbl_smallint` AS `tbl_smallint` WHERE (`a` = ?)") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: afb464d5 |
+------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.03 sec)
Da mesma forma, se um valor constante em uma consulta exceder o intervalo do tipo, o PolarDB-X também o trunca antes do roteamento. Portanto, para a tabela tbl_smallint, o PolarDB-X roteia consultas para a=12345678 e a=32767 para a mesma partição.
Conversão de tipo para colunas de partição
Se uma constant expression em uma consulta ou instrução INSERT tiver um tipo de dados diferente da partition column, o PolarDB-X realiza uma implicit type conversion na expressão constante e então usa o valor convertido para o routing calculation. No entanto, a type conversion pode falhar. Por exemplo, a string abc não pode ser convertida para um inteiro.
Quando ocorre ou falha a type conversion para uma partition column, o PolarDB-X comporta-se de maneira diferente dependendo se a instrução é DQL, DML ou DDL:
-
DQL(especificamente paratype conversionenvolvendo umapartition columnem uma cláusulaWHERE)Conversão bem-sucedida: O PolarDB-X usa o valor convertido para o
partition routing.Falha na conversão: O PolarDB-X ignora a condição na
partition column, resultando em umfull table scan.
-
DML(especificamente para instruçõesINSERTouREPLACE)Conversão bem-sucedida: O PolarDB-X usa o valor convertido para o
partition routing.Falha na conversão: O PolarDB-X rejeita a instrução e retorna um erro.
-
DDL(especificamente para instruçõesDDLrelacionadas apartitioned tables, comoCREATE TABLEeSPLIT PARTITION)Conversão bem-sucedida: O PolarDB-X rejeita a instrução e retorna um erro. Instruções
DDLnão permitemimplicit type conversion.Falha na conversão: O PolarDB-X rejeita a instrução e retorna um erro.
Diferenças de sintaxe em relação às tabelas particionadas do MySQL
|
Diferença |
MySQL |
PolarDB-X |
|
Inclusão da chave primária na chave de particionamento |
Obrigatório. |
Não obrigatório. |
|
Particionamento Key |
Algoritmo de roteamento: Operação de módulo no número de partições. |
Algoritmo de roteamento: Algoritmo de hash consistente. |
|
Particionamento Hash |
|
|
|
Função de particionamento |
Suportado. Para |
Suportado com limitações. Para
|
|
Tipos de dados da coluna de particionamento |
O particionamento Key suporta todos os tipos de dados. |
O particionamento Key suporta apenas tipos de dados inteiros, de data/hora e string. |
|
Conjunto de caracteres da coluna de particionamento |
Suporta todos os conjuntos de caracteres comuns. |
Suporta apenas os seguintes conjuntos de caracteres:
|
|
Subparticionamento |
Suportado. |
Suportado. |
Suportado
Não suportado