PolarDB-X vous permet de créer des tables partitionnées afin de répondre à vos besoins métier en spécifiant une clause de partitionnement. PolarDB-X prend en charge les quatre types de partitionnement suivants :
Partitionnement par hachage : cette stratégie achemine les données en appliquant un algorithme de hachage cohérent intégré à la valeur d'une colonne de partition ou à l'expression d'une fonction de partition. Le partitionnement par hachage se subdivise en deux stratégies, Key partitioning et Hash partitioning, selon qu'une expression de fonction de partition ou plusieurs colonnes de partition peuvent être utilisées comme clé de partition.
Partitionnement par plage : cette stratégie achemine les données en comparant la valeur d'une colonne de partition ou d'une expression de fonction de partition avec des plages de partition prédéfinies. Le partitionnement par plage se subdivise en deux stratégies, Range Columns partitioning et Range partitioning, selon qu'une expression de fonction de partition ou plusieurs colonnes de partition peuvent être utilisées comme clé de partition.
Partitionnement par liste : à l'instar du partitionnement par plage, cette stratégie achemine les données en vérifiant si la valeur d'une colonne de partition ou d'une expression de fonction de partition figure dans une liste de valeurs prédéfinie pour une partition. Le partitionnement par liste se subdivise en deux stratégies, List Columns partitioning et List partitioning, selon que plusieurs colonnes de partition sont utilisées comme clé de partition et selon la manière dont elles le sont.
CoHash. Il s'agit d'une stratégie de partitionnement par hachage étendue proposée par PolarDB-X, conçue pour des scénarios d'application courants et spécifiques. Cette stratégie permet le partitionnement horizontal d'une table basé sur plusieurs colonnes de partition corrélées.
Type de hachage
Dans PolarDB-X, il existe deux types de partitionnement basés sur le hachage : le partitionnement par hachage et le partitionnement par clé. Tous deux font partie de la syntaxe standard de partitionnement dans MySQL natif. Pour activer des fonctionnalités flexibles de gestion des partitions, telles que le fractionnement, la fusion et la migration des partitions, ainsi que pour prendre en charge le fractionnement des points chauds pour les clés de partition vectorielles, PolarDB-X redéfinit le routage pour le partitionnement par hachage et par clé ; bien que la syntaxe reste compatible avec la syntaxe MySQL CREATE TABLE, l'implémentation sous-jacente du partition routing diffère de celle de MySQL. Le tableau suivant décrit les différences entre le partitionnement par clé et le partitionnement par hachage :
Tableau 1. Comparaison des stratégies de partitionnement par clé et par hachage
|
Stratégie de partitionnement |
Prise en charge des clés de partition |
Prise en charge des fonctions de partitionnement |
Exemple de syntaxe |
Fonctionnalités et limites |
Routage (requête ponctuelle) |
|
Key (stratégie de partitionnement par défaut) |
Clé de partition sur une seule colonne |
Non |
PARTITION BY KEY(c1) |
|
|
|
Clé de partition vectorielle |
Non |
PARTITION BY KEY(c1, c2, ..., cn) |
|
|
|
|
Hash |
Clé de partition sur une seule colonne |
Non |
PARTITION BY HASH(c1) |
|
|
|
Oui |
PARTITION BY HASH(YEAR(c1)) |
|
|||
|
Clé de partition vectorielle |
Non |
PARTITION BY HASH(c1, c2, ..., cn) |
|
|
Exemple 1-1 : Partition Key
Le partitionnement Key est également la méthode de partitionnement par défaut dans PolarDB-X. Cette méthode prend en charge les clés de partition vectorielles. Par exemple, l'instruction suivante crée une table partitionnée par le nom d'utilisateur (name) et l'ID utilisateur (id) en huit partitions :
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;
Pour une table partitionnée qui utilise une partition KEY avec une clé de partition vectorielle, le routage dépend par défaut uniquement de la première colonne de partition (name). Par conséquent, l'élagage de partition est déclenché lorsque la clause WHERE contient une condition d'égalité pour cette première colonne de partition. Par exemple :
## This query triggers partition pruning and scans only a single partition.
SELECT id from key_tbl where name='Jack';
Si la première colonne de partition, name, provoque un déséquilibre des données ou un point chaud de données, vous pouvez effectuer un fractionnement de partition en utilisant la prochaine colonne de partition, telle que id. Pour plus de détails, consultez Modifier une partition au niveau du groupe de tables (mode AUTO).
Si une clé de partition vectorielle avec N colonnes de partition utilise ses K premières colonnes pour le routage (1 ≤ K ≤ N), l'inclusion de conditions sur les colonnes de partition préfixées (les K premières colonnes) dans la clause WHERE permet l'élagage de partition.
Exemple 1-2 : Partitionnement Hash
Pour utiliser un ID utilisateur comme clé de partition pour le partitionnement horizontal, créez la table en utilisant le partitionnement Hash et spécifiez 8 partitions :
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;
Le partitionnement Hash prend en charge les expressions de fonction de partitionnement, telles que YEAR() et TO_DAYS(), pour convertir les valeurs de types temporels en types entiers. Par exemple, pour partitionner une table par la colonne birthday en 8 partitions Hash, utilisez l'instruction suivante :
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;
Actuellement, PolarDB-X prend en charge les fonctions de partitionnement suivantes :
YEAR
MONTH
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
TO_DAYS
TO_MONTHS
TO_WEEKS
TO_SECONDS
UNIX_TIMESTAMP
SUBSTR/SUBSTRING
Pour les fonctions SUBSTR/SUBSTRING, la clé de partition doit être de type chaîne ; pour toutes les autres fonctions de partition, elle doit être de type temporel (tel que DATE, DATETIME ou TIMESTAMP).
Exemple 1-3 : Extension du partitionnement Hash
Cette rubrique explique la syntaxe DDL, les clauses et les paramètres pour la création de tables partitionnées dans les bases de données PolarDB-X en mode AUTO.
Instructions
Notes
-
Avant d'utiliser la syntaxe pour créer des tables partitionnées, **assurez-vous que la base de données logique actuelle est en mode de partitionnement automatique (
mode='auto')**. Cette syntaxe n'est pas prise en charge dans les autres modes. Vous pouvez exécuter la commandeSHOW CREATE DATABASE db_namepour vérifier le mode de la base de données logique actuelle. Par exemple :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)Pour plus de détails sur la syntaxe
CREATE DATABASE, consultez la rubrique CREATE DATABASE. Si la clé primaire d'une table partitionnée n'inclut pas la clé de partition et n'est pas une clé primaire à incrémentation automatique, vous devez garantir l'unicité de la clé primaire au niveau de l'application.
Pour utiliser la fonctionnalité de sous-partitionnement, la version de l'instance doit être 5.4.17-16952556 ou ultérieure.
Syntaxe
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(...)
La syntaxe DDL de PolarDB-X repose sur MySQL. La syntaxe ci-dessus met en évidence les principales différences. Pour la syntaxe complète, consultez la documentation MySQL.
Glossaire
Clé de partition : Une ou plusieurs colonnes d'une table partitionnée utilisées pour le partitionnement horizontal.
Colonne de partition : Colonne utilisée pour le routage et le calcul des partitions dans une table partitionnée horizontalement. Elle fait généralement partie d'une clé de partition.
Clé de partition vectorielle : Clé de partition composée d'une ou plusieurs colonnes de partition.
Clé de partition monocolumnne : Clé de partition constituée d'une seule colonne de partition.
Colonne de partition préfixe : Pour une clé de partition vectorielle comportant N (N > 1) colonnes de partition, son préfixe est constitué des K premières colonnes, où 1 <= K < N.
Fonction de partition : Fonction qui accepte une colonne de partition en entrée. Sa sortie fournit la valeur utilisée pour les calculs de routage.
Élagage de partition : Technique d'optimisation des requêtes qui évite l'analyse des partitions inutiles en se basant sur les définitions de partition et les conditions de requête.
Fractionnement des points chauds : Technique d'équilibrage de charge qui divise une partition chaude en utilisant la colonne de partition suivante. Ce fractionnement est déclenché lorsque les colonnes de partition préfixes d'une clé de partition vectorielle rencontrent des points d'accès chauds ou une distribution inégale des données.
Partition physique : Partition mappée un à un avec une sous-table physique sur un nœud DN.
Partition logique : Partition virtuelle mappée à une ou plusieurs partitions physiques. Par exemple, dans une table créée avec sous-partitionnement, les partitions de premier niveau sont des partitions logiques.
Paramètres
|
Paramètre |
Description |
|
|
Spécifie le jeu de caractères par défaut pour les colonnes de la table. Les jeux de caractères suivants sont pris en charge :
|
|
|
Spécifie l'interclassement par défaut pour les colonnes de la table. Les interclassements suivants sont pris en charge :
|
|
|
Spécifie le groupe de tables pour la table partitionnée. Si ce paramètre est omis, le système recherche ou crée automatiquement un groupe de tables compatible correspondant à la méthode de partitionnement de la table. |
|
|
Spécifie les nœuds de données qui stockent la table partitionnée. |
Tableau 3. Comparaison des stratégies de partitionnement List Columns et List
|
Stratégie de partitionnement |
Prise en charge de la clé de partition |
Prise en charge de la fonction de partitionnement |
Exemple de syntaxe |
Fonctionnalités et limites |
Routage (requête ponctuelle) |
|
List Columns |
Clé de partition sur une seule colonne et clé de partition vectorielle |
Non |
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) ), ...) |
Le fractionnement des points chauds n'est pas pris en charge. |
|
|
List |
Clé de partition sur une seule colonne |
Oui |
PARTITION BY LIST(YEAR(c1)) ( PARTITION p1 VALUES IN (2018,2019), PARTITION p2 VALUES IN (2020,2021) ...) |
Le fractionnement des points chauds n'est pas pris en charge. |
Exemple 3-1 : Partitionnement List Columns
Le list columns partitioning prend en charge les vector partition keys. Par exemple, le list columns partitioning vous permet de partitionner les commandes par pays et par ville. La table creation syntax est la suivante :
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'))
);
Le List Columns partitioning ne prend actuellement pas en charge les types de données contenant des informations de fuseau horaire, tels que TIMESTAMP et TIME, en tant que partition key.
Exemple 3-2 : Partitionnement List
Bien que le list partitioning ne prenne en charge qu'une single-column partition key, vous pouvez utiliser des partition function expressions telles que YEAR, MONTH, DAYOFMONTH, TO_DAYS et TO_SECONDS pour convertir les valeurs d'une partition column de time-type en un integer type.
Par exemple, pour créer une list partition basée sur l'année de la colonne order_time, utilisez la syntaxe create table suivante :
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)
);
Le partitionnement ne prend en charge que l'integer type comme partition key. Le string type n'est pas pris en charge en tant que partition column.
Exemple 3-3 : Partitions List Columns et List avec une partition par défaut
PolarDB-X permet de créer des list columns partitions et des list partitions incluant une default partition vers laquelle sont routées les données non définies dans les regular partitions.
Vous ne pouvez définir qu'une seule partition par défaut, qui doit être la dernière partition.
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
-
Restrictions relatives aux types de données
Types entiers : BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT et TINYINT UNSIGNED.
Types temporels : DATETIME et DATE.
Types chaîne : CHAR et VARCHAR.
-
Restrictions syntaxiques
Le partitionnement List Columns ne prend pas en charge le type de données TIMESTAMP.
Le partitionnement List prend uniquement en charge les types entiers.
Ni le partitionnement List Columns ni le partitionnement List ne prennent en charge le fractionnement des points chauds.
Par défaut, le nombre maximal de partitions est de 8 192.
Par défaut, le nombre maximal de colonnes de partition est de 5.
Type CoHash
La stratégie de partitionnement CoHash de PolarDB-X est spécifique à PolarDB-X.
Exigences de version
Utilisez la version 5.4.18-17047709 ou ultérieure.
Cas d'utilisation
Cette stratégie de partitionnement est couramment utilisée dans les scénarios métier suivants :
Si une table possède des colonnes corrélées, telles que c1 et c2 dont les quatre derniers caractères sont toujours identiques, vous pouvez effectuer un partitionnement horizontal sur ces deux colonnes afin d'acheminer les requêtes SQL comportant une condition d'égalité sur l'une ou l'autre colonne vers une seule partition.
Par conséquent, cette stratégie de partitionnement exige que les valeurs restent cohérentes entre plusieurs colonnes de partition au sein d'une même table partitionnée.
Exemple 4-1 : Définir la colocalisation avec des fonctions de partition indépendantes
Supposons que votre application dispose d'une table orders où les colonnes order_id et buyer_id partagent les six derniers chiffres identiques pour chaque ligne. Pour partitionner cette table selon ces chiffres partagés et garantir qu'une requête d'égalité sur l'une ou l'autre colonne soit routée vers la même partition, utilisez la syntaxe suivante :
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;
Exemple 4-2 : Utilisation du sucre syntaxique Range_Hash pour la migration des utilisateurs de la version 1.0 vers la 2.0
Pour une migration de la version 1.0 vers la 2.0, considérons une table orders fragmentée par base de données et par table à l'aide de range_hash, définie comme suit : DBPARTIITION BY RANGE_HASH(. Sa table partitionnée correspondante dans la base de données AUTO 2.0 est définie comme suit :
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;
PolarDB-X convertit automatiquement la syntaxe RANGE_HASH en une définition de partition CO_HASH. Par exemple, RANGE_HASH(order_id, buyer_Id, 6) devient la définition CO_HASH suivante :
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;
Différences clés par rapport au partitionnement hash/key
Étant donné que les stratégies de partitionnement CoHash et hash/key sont similaires, cette section décrit leurs principales similitudes et différences d'utilisation.
|
Principales différences |
CO_HASH |
KEY |
HASH |
|
Exemple de syntaxe |
PARTITION BY CO_HASH(c1, c2) PARTITIONS 8 |
PARTITION BY KEY(c1, c2) PARTITIONS 8 |
PARTITION BY HASH(c1, c2) PARTITIONS 8 |
|
Clé de partition sur une seule colonne |
Non pris en charge |
Pris en charge |
Pris en charge |
|
Clé de partition vectorielle |
Pris en charge |
Pris en charge |
Pris en charge |
|
Utilisation de fonctions de partition sur les colonnes de partition vectorielles |
Pris en charge. Par exemple : PARTITION BY CO_HASH( Extrait les 4 derniers caractères de c1 RIGHT(c1, 4), / Extrait les 4 derniers caractères de c2 / RIGHT(c2, 4) ) PARTITIONS 8 |
Non pris en charge |
Non pris en charge |
|
Relation entre les colonnes de partition |
Une relation de co-localisation. L'application doit fournir et maintenir cette relation entre les valeurs des colonnes de partition. Par exemple :
|
Similaire à la relation de préfixe d'un index composite. |
Similaire à la relation de préfixe d'un index composite. |
|
Élimination des partitions pour les requêtes d'égalité sur les colonnes de préfixe |
Pris en charge. Par exemple :
|
Pris en charge. Par exemple :
|
Non pris en charge. L'élimination des partitions nécessite des conditions d'égalité sur toutes les colonnes de partition. Par exemple :
|
|
Élimination des partitions pour les requêtes d'égalité sur les colonnes non préfixées |
Pris en charge. Les conditions d'égalité sur n'importe quelle colonne de partition peuvent déclencher indépendamment l'élimination des partitions. Par exemple :
|
Non pris en charge. Les conditions d'égalité sur les colonnes de partition non préfixées nécessitent une analyse complète des partitions. Par exemple :
|
Non pris en charge. Les conditions d'égalité sur les colonnes de partition non préfixées nécessitent une analyse complète des partitions. Par exemple :
|
|
Requêtes de plage |
Non pris en charge. Entraîne une analyse complète des partitions. |
Non pris en charge. Entraîne une analyse complète des partitions. |
Non pris en charge. Entraîne une analyse complète des partitions. |
|
description du routage (requête ponctuelle) |
|
Voir la comparaison du partitionnement KEY et HASH dans les lignes ci-dessus. |
Voir la comparaison du partitionnement KEY et HASH dans les lignes ci-dessus. |
|
Division de point chaud |
Non pris en charge. Vous ne pouvez pas diviser davantage une partition en fonction d'une valeur de point chaud spécifique, telle que |
Pris en charge |
Non pris en charge |
|
Gestion des partitions (par exemple, division, fusion et migration des partitions) |
Pris en charge |
Pris en charge |
Pris en charge |
|
Sous-partitionnement |
Pris en charge |
Pris en charge |
Pris en charge |
Considérations
-
Votre service doit maintenir la relation coordonnée entre les valeurs des colonnes de partition ; PolarDB-X valide uniquement les résultats de routage. Lorsque vous utilisez le partitionnement
CO_HASH, PolarDB-X vérifie que toutes les valeurs de colonne de partition spécifiées pour une ligne sont acheminées vers le même shard. Toutefois, il ne valide pas si les valeurs elles-mêmes respectent la relation coordonnée. Cette application relève de la responsabilité de votre service.Par exemple, supposons que votre service exige que les quatre derniers caractères des colonnes c1 et c2 soient identiques. Si une valeur pour c1, telle que 100234, et une valeur pour c2, telle que 1320, sont toutes deux acheminées vers le shard 0, PolarDB-X autorise l'opération
insert (c1,c2) values (100234,1320)car le routage est cohérent. Cependant, cette opération viole la règle de service, car les quatre derniers caractères de c1 (0234) et de c2 (1320) ne sont pas les mêmes.
-
Restrictions DML sur la modification des colonnes de partition Étant donné que le partitionnement CO_HASH met en corrélation les valeurs de plusieurs colonnes de partition, PolarDB-X applique les restrictions suivantes aux opérations DML qui modifient ces colonnes afin d'éviter une distribution incorrecte des données :
Pour les instructions insert et replace, si les valeurs des différentes colonnes de partition dans une seule ligne de la clause
VALUESrésolvent vers des partitions différentes, PolarDB-X rejette l'opération.Pour les instructions update et upsert, vous devez modifier toutes les colonnes de partition simultanément dans la clause
SET. Par exemple, si c1 et c2 sont des colonnes de partition, vous devez utiliser une instruction telle queUPDATE t1 SET c1='xx',c2='yy' WHERE id=1. Si les nouvelles valeurs des différentes colonnes de partition dans une seule ligne résolvent vers des partitions différentes, PolarDB-X rejette l'instruction.Lorsque CO_HASH est la stratégie de partitionnement d'un index secondaire global (GSI), PolarDB-X rejette également toute opération DML sur la table principale qui entraîne la résolution des valeurs des différentes colonnes de partition dans une seule ligne GSI vers des partitions différentes.
Gestion des zéros non significatifs pour les types entiers. Étant donné que les
partition columnsdans une stratégieCO_HASHsont corrélées, vous les définissez souvent à l'aide d'unepartition functiontelle queSUBSTR,LEFTouRIGHT. Ce processus peut entraîner l'apparition de zéros non significatifs lors de la troncature des entiers. Par exemple, supposons que votre logique métier exige que les quatre derniers caractères dec1etc2soient identiques. Sic1vaut1000034, les quatre derniers caractères correspondent à lastring'0034'. Pour unepartition columndeinteger type,CO_HASHconvertit automatiquement toute valeur tronquée vers leinteger typede cette colonne avant lerouting. Ainsi,CO_HASHtransforme lastring'0034'en l'entier34, calcule lahash valueet achemine la ligne. Ce processus gère automatiquement les zéros non significatifs.
Limitations des fonctions de partitionnement
RIGHT
LEFT
SUBSTR
Restrictions relatives aux types de données
types entiers : BIGINT, BIGINT UNSIGNED, INT, INT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, SMALLINT, SMALLINT UNSIGNED, TINYINT et TINYINT UNSIGNED
type à virgule fixe : DECIMAL (avec une échelle de 0)
types temporels : non pris en charge
types chaîne : CHAR et VARCHAR
Restrictions syntaxiques
Vous ne pouvez pas utiliser de fonctions de partitionnement imbriquées, telles que
SUBSTR(SUBSTR(c1,-6),-4), sur une colonne de partitionnement.
Lorsque vous utilisez le sucre syntaxique
RANGE_HASH, le paramètre de longueur ne doit pas être négatif.-
Toutes les colonnes de partitionnement doivent avoir exactement le même type de données, y compris les propriétés suivantes :
Jeu de caractères et interclassement
Longueur et précision
Par défaut, le nombre maximal de partitions est de 8 192.
Par défaut, le nombre maximal de colonnes de partitionnement est de 5.
Sous-partitionnement
À l'instar de MySQL, PolarDB-X prend en charge la syntaxe de sous-partitionnement pour créer des tables partitionnées avec des sous-partitions. Le sous-partitionnement divise davantage chaque partition en fonction d'une colonne de partitionnement et d'une stratégie de partitionnement spécifiées.
Dans une table partitionnée à deux niveaux, chaque partition de premier niveau est une partition logique qui correspond à un ensemble de partitions de second niveau.
Chaque partition de second niveau est une partition physique qui correspond à un shard de table physique spécifique sur un nœud DN.
Modèles avec et sans gabarit
Les partitions de second niveau de PolarDB-X se divisent en deux catégories principales : avec gabarit (templated) et sans gabarit (non-templated) :
sous-partition avec gabarit : le nombre de sous-partitions et leurs valeurs limites de partition sont identiques pour chaque partition.
sous-partition sans gabarit : le nombre de sous-partitions et leurs valeurs limites de partition peuvent différer d'une partition à l'autre.
Restrictions syntaxiques
Par défaut, une table partitionnée utilisant le sous-partitionnement ne peut pas comporter plus de 8 192 partitions physiques.
Lorsque vous utilisez des partitions sans gabarit, tous les noms de sous-partitions doivent être uniques et ne doivent correspondre à aucun nom de partition.
Lorsque vous utilisez des partitions avec gabarit, tous les noms de sous-partitions dans le gabarit doivent être uniques et ne doivent correspondre à aucun nom de partition.
Avec le sous-partitionnement, le nombre total de partitions physiques dans une table correspond au nombre total de sous-partitions across toutes les partitions. Ce nombre peut augmenter rapidement. Par conséquent, gérez avec soin le nombre de partitions et de sous-partitions afin d'éviter une dégradation des performances due à un sur-partitionnement ou des erreurs liées au dépassement de la limite totale de partitions.
Exemple 5-1 : Partition secondaire avec gabarit
/*
* 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)
);
Exemple 5-2 : Sous-partition sans gabarit
/*
* 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
);
Partitionnement automatique
Par défaut, le automatic partitioning est désactivé pour les bases de données en AUTO mode. Pour activer cette fonctionnalité, exécutez la commande suivante :
SET GLOBAL AUTO_PARTITION=true;
Lorsque le partitionnement automatique est activé :
-
Lorsque vous créez une table sans spécifier de clé de partitionnement, PolarDB-X partitionne la table par défaut en utilisant sa clé primaire. Si la table ne possède pas de clé primaire, il utilise la clé primaire implicite. Ce processus utilise le partitionnement KEY, ce qui donne une table partitionnée de niveau 1.
Par défaut, le nombre de partitions est huit fois supérieur au nombre de nœuds logiques dans l'instance. Par exemple, si une instance PolarDB-X est créée avec deux nœuds logiques, le nombre de partitions par défaut est de 16.
En plus du partitionnement de la table principale, PolarDB-X partitionne également tous ses index par défaut. La clé de partitionnement d'un index est constituée des colonnes d'index et des colonnes de clé primaire de la table.
L'exemple suivant illustre la syntaxe MySQL standard pour la création d'une table, où id est la clé primaire et name est la colonne indexée :
CREATE TABLE auto_part_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id),
index idx_name (name)
);
L'exécution de l'instruction SHOW CREATE TABLE affiche la syntaxe standard de création de table MySQL et masque automatiquement toutes les informations de partitionnement :
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)
L'exécution de l'instruction SHOW FULL CREATE TABLE affiche toutes les informations de partitionnement pour la table principale et ses tables d'index :
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)
Tables simples
Dans PolarDB-X, vous pouvez créer des tables non partitionnées en utilisant le mot-clé SINGLE. Par exemple :
CREATE TABLE single_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) SINGLE;
Tables de diffusion
Dans PolarDB-X, vous pouvez créer des tables de diffusion en spécifiant le mot-clé BROADCAST. Une table de diffusion contient une copie identique de ses données sur tous les nœuds de données. Par exemple :
CREATE TABLE broadcast_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) BROADCAST;
PolarDB-X étend la syntaxe du partitionnement par hachage pour prendre en charge une clé de partition vectorielle. Contrairement à la syntaxe standard de partitionnement de MySQL natif, PolarDB-X vous permet d'effectuer un partitionnement sur plusieurs colonnes avec la méthode HASH. Utilisez l'instruction suivante :
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;
Contrairement au partitionnement par clé, le partitionnement par hachage utilise une clé de partition vectorielle, où toutes les colonnes de partition contribuent aux calculs de hachage et de routage lors du routage des partitions. Par conséquent, pour activer l'élimination des partitions (partition pruning), la clause WHERE d'une requête SQL doit spécifier des conditions d'égalité pour toutes les colonnes de partition. Par exemple, SQL1 peut déclencher l'élimination des partitions sur la table hash_tbl2, mais pas SQL2 :
##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';
Étant donné que le partitionnement par hachage utilise l'intégralité de la clé de partition pour calculer la valeur de hachage en amont, il distribue théoriquement les données de manière plus uniforme que le partitionnement par clé utilisant une clé de partitionnement vectorielle. Toutefois, il ne prend pas en charge le fractionnement des points chauds (hotspot splitting), car aucune colonne supplémentaire n'est disponible pour diviser une partition chaude.
Limitations
-
Limitations relatives aux types de données
Types entiers :
BIGINT,BIGINT UNSIGNED,INT,INT UNSIGNED,MEDIUMINT,MEDIUMINT UNSIGNED,SMALLINT,SMALLINT UNSIGNED,TINYINTetTINYINT UNSIGNED.Types temporels :
DATETIME,DATEetTIMESTAMP.Types chaîne :
CHARetVARCHAR.
-
Limitations syntaxiques
Lors de l'utilisation d'une fonction de partition avec une clé de partition monocolumnne pour un partitionnement par hachage, la clé doit être de type temporel.
Une clé de partition vectorielle pour un partitionnement par hachage ne prend pas en charge les fonctions de partition ni le fractionnement des points chauds.
Par défaut, le nombre maximal de partitions est de 8 192.
Par défaut, le nombre maximal de colonnes de partition est de 5.
Uniformité des données
L'algorithme de hachage cohérent intégré pour le partitionnement par clé et le partitionnement par hachage est MurmurHash3, un algorithme haute performance présentant une faible probabilité de collision.
Avec MurmurHash3, la distribution des données pour le partitionnement par clé et le partitionnement par hachage devient généralement équilibrée uniquement lorsque le nombre de valeurs distinctes de la clé de partition (N) dépasse 3 000. Plus la valeur de N est élevée, plus la distribution des données est équilibrée.
Type Range
Dans PolarDB-X, il existe deux types de partitionnement par plage : le partitionnement par plage (range partition) et le partitionnement par colonnes de plage (range columns partition). Tous deux font partie de la syntaxe standard de partitionnement de MySQL natif. Le tableau suivant compare ces deux types de partitionnement.
Tableau 2. Comparaison des stratégies de partitionnement Range Columns et Range
|
Stratégie de partitionnement |
Prise en charge des clés de partition |
Prise en charge des fonctions de partition |
Exemple de syntaxe |
Fonctionnalités et limites |
Routage (requête ponctuelle) |
|
Range Columns |
Clés de partition à colonne unique et vectorielles |
Non |
PARTITION BY RANGE COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES LESS THAN (1,10,...,1000), PARTITION p2 VALUES LESS THAN (2,20,...,2000) ...) |
Prend en charge le fractionnement des points chauds. Par exemple, si la colonne |
|
|
Range |
Clé de partition à colonne unique |
Oui |
PARTITION BY RANGE(YEAR(c1)) ( PARTITION p1 VALUES LESS THAN (2019), PARTITION p2 VALUES LESS THAN (2021) ...) |
|
|
Exemple 2-1 : Partitionnement par colonnes de plage (Range Columns)
Le partitionnement Range Columns prend en charge une clé de partition vectorielle, mais pas les fonctions de partition. Par exemple, pour partitionner une table selon l'ID de commande et la date de commande, spécifiez la syntaxe CREATE TABLE suivante :
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)
);
Le partitionnement Range Columns ne prend pas en charge les types de données sensibles au fuseau horaire, tels que TIMESTAMP et TIME, en tant que clé de partition.
Exemple 2-2 : Partitionnement par plage (Range)
Le partitionnement Range ne prend en charge qu'une clé de partition à colonne unique. Toutefois, pour une colonne de partition de type datetime, vous pouvez utiliser des fonctions de partition telles que YEAR, TO_DAYS, TO_SECONDS ou MONTH afin de convertir ses valeurs en entiers.
Le partitionnement Range ne prend pas directement en charge les types de chaînes comme colonne de partition.
Par exemple, pour créer des partitions trimestrielles sur la colonne order_time à l'aide du partitionnement Range, utilisez la syntaxe suivante :
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)
);
Le partitionnement Range ne prend en charge qu'une seule colonne de type entier comme clé de partition.
Limites
-
Restrictions relatives aux types de données
Types d'entiers :
BIGINT,BIGINT UNSIGNED,INT,INT UNSIGNED,MEDIUMINT,MEDIUMINT UNSIGNED,SMALLINT,SMALLINT UNSIGNED,TINYINTetTINYINT UNSIGNED.Types datetime :
DATETIMEetDATE.Types de chaînes :
CHARetVARCHAR.
-
Restrictions syntaxiques
Le partitionnement
RANGE COLUMNSet le partitionnementRANGEne prennent pas en charge l'utilisation d'une valeurNULLcomme valeur limite.Le partitionnement
RANGE COLUMNSne prend pas en charge le type de donnéesTIMESTAMP.Le partitionnement
RANGEne prend en charge que les types d'entiers. Si la clé de partition utilise le typeTIMESTAMP, vous devez utiliser la fonctionUNIX_TIMESTAMPpour garantir la cohérence du fuseau horaire.Le partitionnement
RANGEne prend pas en charge le fractionnement des points chauds.Lors des requêtes, les valeurs
NULLsont traitées comme la valeur minimale pour le routage des partitions.Par défaut, le nombre maximal de partitions est de 8 192.
Par défaut, le nombre maximal de colonnes de partitionnement est de 5.
Type List
À l'instar du range type, PolarDB-X subdivise davantage la list partitioning policy en deux types : list partitioning et list columns partitioning. Ces deux types utilisent la syntaxe de partitionnement standard de MySQL natif. De plus, PolarDB-X prend en charge une default partition pour le list partitioning et le list columns partitioning. Ce tableau compare ces deux types :
La sortie affiche les informations suivantes :
Par défaut, la table principale
auto_part_tblest partitionnée par la colonneidà l'aide du partitionnementKEYen 16 partitions.Par défaut, l'index
idx_namesur la table principale est un index global qui utilise les colonnesnameetidcomme clé de partition et comporte 16 partitions.
Partitionnement manuel
Créez une table partitionnée manuellement en spécifiant une colonne de partition, une fonction de partition et un type de partition dans l'instruction CREATE TABLE. Pour plus d'informations sur les types de partition, consultez Créer manuellement une table partitionnée (mode AUTO).
Types de données
Tableau 4. Types de données pris en charge pour les colonnes de clé de partition selon le type de partitionnement
|
Type de données |
Partitionnement par hachage |
Partitionnement par plage |
Partitionnement par liste |
|||||
|
Hachage |
Clé |
Plage |
Colonnes de plage |
Liste |
Colonnes de liste |
|||
|
Colonne de clé de partition unique |
Plusieurs colonnes de clé de partition |
|||||||
|
Type entier |
TINYINT |
|
|
|
|
|
|
|
|
TINYINT UNSIGNED |
|
|
|
|
|
|
|
|
|
SMALLINT |
|
|
|
|
|
|
|
|
|
SMALLINT UNSIGNED |
|
|
|
|
|
|
|
|
|
MEDIUMINT |
|
|
|
|
|
|
|
|
|
MEDIUMINT UNSIGNED |
|
|
|
|
|
|
|
|
|
INT |
|
|
|
|
|
|
|
|
|
INT UNSIGNED |
|
|
|
|
|
|
|
|
|
BIGINT |
|
|
|
|
|
|
|
|
|
BIGINT UNSIGNED |
|
|
|
|
|
|
|
|
|
Type à virgule fixe |
DECIMAL |
(Fonctions de partition non prises en charge.) |
|
|
|
|
|
|
|
Type date et heure |
DATE |
|
|
|
|
|
|
|
|
DATETIME |
|
|
|
|
|
|
|
|
|
TIMESTAMP |
|
|
|
|
|
|
|
|
|
Type chaîne |
CHAR |
|
|
|
|
|
|
|
|
VARCHAR |
|
|
|
|
|
|
|
|
Type binaire |
BINARY |
|
|
|
|
|
|
|
|
VARBINARY |
|
|
|
|
|
|
|
Types de données des clés de partition et routage
Le routage d'une table partitionnée dépend directement du type de données de la clé de partition, en particulier pour les partitions par clé et par hachage. Les différents types de données utilisent des algorithmes de hachage ou une logique de comparaison distincts (tels que la sensibilité à la casse), ce qui entraîne des comportements de routage différents. (Remarque : le routage des partitions dans MySQL dépend également fortement du type.)
Cet exemple présente deux tables, tbl_int et tbl_bigint, toutes deux dotées de 1 024 partitions. La table tbl_int utilise une clé de partition de type int, tandis que tbl_bigint utilise une clé de partition de type bigint. Bien qu'il s'agisse de deux types entiers, cette différence fait en sorte que la même valeur de requête (12345678) est routée vers des partitions différentes :
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)
Sensibilité à la casse, jeu de caractères et interclassement
Le jeu de caractères et l'interclassement d'une clé de partition influencent directement l'algorithme de routage d'une table partitionnée. Ils déterminent notamment si le routage est sensible à la casse. Si l'interclassement d'une table est sensible à la casse, le hachage et la comparaison effectués lors du routage le sont également. À l'inverse, si l'interclassement n'est pas sensible à la casse, ces opérations ne le sont pas non plus. Par défaut, une clé de partition de type chaîne utilise le jeu de caractères utf8 et l'interclassement non sensible à la casse utf8_general_ci.
Exemple 1
Pour rendre le routage de la clé de partition sensible à la casse, définissez l'interclassement de la table sur une option sensible à la casse, telle que utf8_bin, lors de sa création. Dans l'exemple ci-dessous, la table tbl_varchar_cs utilise CHARACTER SET utf8 COLLATE utf8_bin. Par conséquent, elle route les chaînes « AbcD » et « abcd », qui ne diffèrent que par la casse, vers des partitions différentes :
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)
Exemple 2
Pour rendre le routage par clé de partition insensible à la casse, définissez l'interclassement (collation) de la table sur une valeur insensible à la casse, telle que utf8_general_ci, lors de sa création. Dans l'exemple ci-dessous, la table tbl_varchar_ci utilise CHARACTER SET utf8 COLLATE utf8_general_ci. Par conséquent, les chaînes 'AbcD' et 'abcd' sont routées vers la même partition :
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)
Modifications du jeu de caractères et de l'interclassement
L'algorithme de routage d'une table partitionnée étant déterminé par le type de données de sa clé de partition, toute modification du jeu de caractères ou de l'interclassement de cette clé déclenche une redistribution de toutes les données de la table. Faites donc preuve de prudence lorsque vous modifiez le type de données d'une clé de partition.
Troncature et conversion de type pour les colonnes de partition
Troncature de type pour les colonnes de partition
Si une expression constante dans une requête ou une instruction INSERT dépasse la plage valide du type de données de la colonne de partition, PolarDB-X tronque d'abord la valeur, puis l'utilise pour le calcul de routage.
Par exemple, la table tbl_smallint possède une colonne de partition de type smallint, dont la plage valide s'étend de -32768 à 32767. Si vous tentez d'insérer une valeur hors de cette plage, comme 12345678 ou -12345678, PolarDB-X tronque d'abord la valeur à la valeur maximale ou minimale du type smallint (respectivement 32767 ou -32768). L'exemple suivant illustre ce processus.
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)
De même, si une valeur constante dans une requête dépasse la plage du type, PolarDB-X la tronque également avant le routage. Ainsi, pour la table tbl_smallint, PolarDB-X route les requêtes pour a=12345678 et a=32767 vers la même partition.
Conversion de type pour les colonnes de partition
Si une expression constante dans une requête ou une instruction INSERT présente un type de données différent de celui de la colonne de partition, PolarDB-X effectue une conversion implicite de type sur l'expression constante, puis utilise la valeur convertie pour le calcul de routage. Toutefois, la conversion de type peut échouer. Par exemple, la chaîne abc ne peut pas être convertie en entier.
Lorsqu'une conversion de type pour une colonne de partition se produit ou échoue, PolarDB-X adopte un comportement différent selon que l'instruction est de type DQL, DML ou DDL :
-
DQL(spécifiquement pour laconversion de typeimpliquant unecolonne de partitiondans une clauseWHERE)Conversion réussie : PolarDB-X utilise la valeur convertie pour le
routage de partition.Échec de la conversion : PolarDB-X ignore la condition sur la
colonne de partition, ce qui entraîne uneanalyse complète de la table.
-
DML(spécifiquement pour les instructionsINSERTouREPLACE)Conversion réussie : PolarDB-X utilise la valeur convertie pour le
routage de partition.Échec de la conversion : PolarDB-X rejette l'instruction et renvoie une erreur.
-
DDL(spécifiquement pour les instructionsDDLrelatives auxtables partitionnées, telles queCREATE TABLEetSPLIT PARTITION)Conversion réussie : PolarDB-X rejette l'instruction et renvoie une erreur. Les instructions
DDLn'autorisent pas laconversion implicite de type.Échec de la conversion : PolarDB-X rejette l'instruction et renvoie une erreur.
Différences de syntaxe par rapport aux tables partitionnées MySQL
|
Différence |
MySQL |
PolarDB-X |
|
Inclusion de la clé primaire dans la clé de partitionnement |
Obligatoire. |
Non obligatoire. |
|
Partitionnement par clé (Key) |
Algorithme de routage : opération modulo sur le nombre de partitions. |
Algorithme de routage : algorithme de hachage cohérent. |
|
Partitionnement par hachage (Hash) |
|
|
|
Fonction de partitionnement |
Prise en charge. Pour |
Prise en charge avec des limitations. Pour
|
|
Types de données des colonnes de partitionnement |
Le partitionnement par clé prend en charge tous les types de données. |
Le partitionnement par clé prend uniquement en charge les types de données entier, date/heure et chaîne. |
|
Jeu de caractères des colonnes de partitionnement |
Prend en charge tous les jeux de caractères courants. |
Prend uniquement en charge les jeux de caractères suivants :
|
|
Sous-partitionnement |
Pris en charge. |
Pris en charge. |
Pris en charge
Non pris en charge