Em bancos de dados PolarDB-X no modo AUTO, a definição de uma chave primária ou única como global (exclusiva em todas as partições) ou local (exclusiva apenas dentro de uma única partição) depende do tipo de tabela e da relação entre as colunas da chave e as colunas da chave de partição.
A regra fundamental para tabelas particionadas manualmente é:
Uma chave primária ou única é global somente se suas colunas incluírem todas as colunas da chave de partição. Caso contrário, ela é local.
Um índice secundário global (GSI) único é sempre global, independentemente da chave de partição.
Referência rápida
|
Tipo de tabela |
Escopo da chave primária |
Escopo da chave única |
|
Tabela comum (SINGLE) |
Global |
Global |
|
Tabela de broadcast (BROADCAST) |
Global |
Global |
|
Tabela com particionamento automático |
Global |
Global |
|
Tabela com particionamento manual — colunas da chave incluem todas as colunas da chave de partição |
Global |
Global |
|
Tabela com particionamento manual — colunas da chave NÃO incluem todas as colunas da chave de partição |
Local |
Local |
|
Tabela com particionamento manual — GSI único |
— |
Global |
Chaves primárias
O PolarDB-X oferece suporte a dois tipos de chaves primárias:
Chave primária global — exclusiva em todas as partições
Chave primária local — exclusiva apenas dentro de uma única partição; valores duplicados podem existir em diferentes partições
Tabelas comuns e tabelas de broadcast
A chave primária de uma tabela comum ou de broadcast é sempre global, pois os dados residem em um único local ou são totalmente replicados.
Exemplo 1: Chaves primárias globais em uma tabela comum e em uma tabela de broadcast
-- A common table
CREATE TABLE single_tbl(
id bigint NOT NULL AUTO_INCREMENT,
name varchar(30),
PRIMARY KEY(id)
) SINGLE;
-- A broadcast table
CREATE TABLE brd_tbl(
id bigint NOT NULL AUTO_INCREMENT,
name varchar(30),
PRIMARY KEY(id)
) BROADCAST;
Tabelas particionadas
Em um banco de dados no modo AUTO, o método de criação da tabela particionada determina se o PolarDB-X gerencia o particionamento automaticamente ou se você o define manualmente:
Tabela com particionamento automático — criada quando nenhuma chave de partição ou algoritmo de particionamento é especificado
Tabela com particionamento manual — criada quando você especifica explicitamente uma chave de partição ou um algoritmo de particionamento
Tabelas com particionamento automático
Todas as chaves primárias em uma tabela com particionamento automático são globais.
Exemplo 2: Chave primária global em uma tabela com particionamento automático
-- An automatic partitioned table
CREATE TABLE auto_tbl(
id bigint NOT NULL AUTO_INCREMENT,
name varchar(30),
PRIMARY KEY(id)
);
Tabelas com particionamento manual
A classificação da chave primária como global ou local depende se as colunas da chave primária abrangem todas as colunas da chave de partição.
Chaves primárias globais
Se as colunas da chave primária incluírem todas as colunas da chave de partição, a chave primária será global.
Exemplo 3: Chave primária global em uma tabela com particionamento manual
A tabela key_tbl é particionada por (id, addr). Como a chave primária (id, name, addr) contém ambas as colunas da chave de partição, trata-se de uma chave primária global.
CREATE TABLE key_tbl(
id bigint,
name varchar(10),
addr varchar(30),
PRIMARY KEY(id, name, addr)
) PARTITION BY KEY(id, addr);
Chaves primárias locais
Caso as colunas da chave primária não incluam todas as colunas da chave de partição, a chave primária será local — exclusiva apenas dentro de cada partição, e não em toda a tabela.
Exemplo 4: Chave primária local em uma tabela com particionamento manual
A tabela list_tbl é particionada por city. Visto que a chave primária (order_id) não inclui city, ela é classificada como uma chave primária local.
CREATE TABLE list_tbl(
order_id bigint,
city varchar(50),
name text,
PRIMARY KEY(order_id)
) PARTITION BY LIST(city)
(
PARTITION p1 VALUES IN ("Beijing"),
PARTITION p2 VALUES IN ("Shanghai"),
PARTITION p3 VALUES IN ("Guangzhou"),
PARTITION p4 VALUES IN ("Shenzhen"),
PARTITION p5 VALUES IN(DEFAULT)
);
Exemplo 5: Chaves primárias locais permitem valores duplicados entre partições
Como list_tbl direciona linhas com base em city, linhas com valores diferentes de city são armazenadas em partições distintas — cada uma aplicando a restrição de chave primária de forma independente.
-
Insira uma linha com
order_id = 10001ecity = "Beijing". Ela será armazenada na partiçãop1.INSERT INTO list_tbl(order_id, city, name) VALUES (10001, "Beijing", "phone"); -- Query OK, 1 row affected -
Insira outra linha com o mesmo
order_idecity = "Beijing". Ambas as linhas iriam para a partiçãop1, resultando em um conflito de chave primária.INSERT INTO list_tbl(order_id, city, name) VALUES (10001, "Beijing", "book"); -- (1062, "ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'TEST_DB_P00000_GROUP' ATOM 'dskey_test_db_p00000_group#polardbx-storage-0-master#11.167.60.147-1766#test_db_p00000': Duplicate entry '10001' for key 'PRIMARY' ") -
Insira uma linha com o mesmo
order_id, mas comcity = "Shenzhen". Essa linha vai para a partiçãop4, evitando conflitos — agora existem duas linhas comorder_id = 10001na tabela.INSERT INTO list_tbl (order_id, city, name) VALUES (10001, "Shenzhen", "camera"); -- Query OK, 1 row affected SELECT * FROM list_tbl; -- +----------+----------+--------+ -- | order_id | city | name | -- +----------+----------+--------+ -- | 10001 | Beijing | phone | -- | 10001 | Shenzhen | camera | -- +----------+----------+--------+ -- 2 rows in set
Exemplo 6: Operações DDL que movem dados entre partições podem falhar devido a erros de chave primária duplicada
Ao modificar a política de particionamento de modo a mesclar partições contendo valores duplicados de chave primária, o PolarDB-X relata um conflito e a operação DDL falha.
Utilizando a tabela list_tbl do Exemplo 5 (que já possui duas linhas com order_id = 10001 nas partições p1 e p4), a instrução a seguir tenta mesclar Beijing e Shenzhen em uma única partição:
ALTER TABLE list_tbl
PARTITION BY LIST (city)
(
PARTITION p1 VALUES IN ("Beijing", "Shenzhen"),
PARTITION p2 VALUES IN ("Shanghai"),
PARTITION p3 VALUES IN ("Guangzhou"),
PARTITION p5 VALUES IN(DEFAULT)
);
-- (4700, "ERR-CODE: [TDDL-4700][ERR_SERVER] server error by Failed to execute the DDL task. Caused by: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] Duplicated entry '10001' for key 'PRIMARY' ")
A falha na DDL ocorre porque colocar ambas as linhas com order_id = 10001 na mesma partição viola a restrição de chave primária local.
Para evitar esse problema, utilize o atributo AUTO_INCREMENT e permita que o PolarDB-X gere as chaves primárias — evite atribuir manualmente valores de chave primária em tabelas com chaves primárias locais.
Se uma tabela com chaves primárias locais já contiver valores duplicados de chave primária, trate os conflitos de dados com cuidado ao sincronizar com sistemas downstream. Por exemplo, ao replicar para o AnalyticDB for MySQL via Data Transmission Service (DTS), podem ocorrer conflitos se o AnalyticDB for MySQL utilizar as colunas de chave primária do PolarDB-X. Nesse caso, defina as chaves primárias do AnalyticDB for MySQL como a combinação completa das colunas de chave primária e das colunas de chave de partição da tabela do PolarDB-X.
Chaves únicas
As chaves únicas seguem as mesmas regras de escopo global/local que as chaves primárias:
Chave única global — exclusiva em todas as partições
Chave única local — exclusiva apenas dentro de uma única partição; valores duplicados podem existir em diferentes partições
Tabelas comuns e tabelas de broadcast
A chave única de uma tabela comum ou de broadcast é sempre global.
Exemplo 7: Chaves únicas globais em uma tabela comum e em uma tabela de broadcast
-- A common table
CREATE TABLE single_tbl(
serial_id bigint,
name varchar(30),
UNIQUE KEY(serial_id)
) SINGLE;
-- A broadcast table
CREATE TABLE brd_tbl(
serial_id bigint,
name varchar(30),
UNIQUE KEY(serial_id)
) BROADCAST;
Tabelas particionadas
Tabelas com particionamento automático
Todas as chaves únicas em uma tabela com particionamento automático são globais.
Exemplo 8: Chave única global em uma tabela com particionamento automático
-- An automatic partitioned table
CREATE TABLE auto_tbl(
serial_id bigint,
name varchar(30),
UNIQUE KEY(serial_id)
);
Tabelas com particionamento manual
Chaves únicas globais
Quando as colunas da chave única incluem todas as colunas da chave de partição, a chave única é global.
Exemplo 9: Chave única global em uma tabela com particionamento manual
A tabela hash_tbl é particionada por type_id. A chave única (inner_id, type_id) inclui a coluna da chave de partição type_id, caracterizando-a como uma chave única global.
CREATE TABLE hash_tbl(
type_id int,
inner_id int,
UNIQUE KEY(inner_id, type_id)
) PARTITION BY HASH(type_id);
Exemplo 10: Chave única global usando um índice secundário global
Um GSI único é sempre uma chave única global, independentemente da chave de partição da tabela. Em key_tbl, u_sid é um GSI único em serial_id — ele garante que serial_id seja exclusivo em todas as partições, mesmo que a tabela seja particionada por type_id.
CREATE TABLE key_tbl(
type_id int,
serial_id int,
UNIQUE GLOBAL INDEX u_sid(serial_id) PARTITION BY HASH(serial_id)
) PARTITION BY HASH(type_id);
Chaves únicas locais
Se as colunas da chave única não incluírem todas as colunas da chave de partição, a chave única será local.
Exemplo 11: Chave única local em uma tabela com particionamento manual
A tabela range_tbl é particionada por order_time. Como a chave única (serial_id) não inclui order_time, ela é uma chave única local.
CREATE TABLE range_tbl(
id int primary key auto_increment,
serial_id int,
order_time datetime NOT NULL,
UNIQUE KEY(serial_id)
) PARTITION BY RANGE(order_time)
(
PARTITION p1 VALUES LESS THAN ('2022-12-31'),
PARTITION p2 VALUES LESS THAN ('2023-12-31'),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
Exemplo 12: Chaves únicas locais permitem valores duplicados entre partições
Dado que range_tbl roteia linhas por order_time, linhas com valores distintos de order_time vão para partições diferentes — cada uma impondo a restrição de chave única independentemente.
-
Insira uma linha com
serial_id = 20001eorder_time = '2022-01-01'. O registro ficará na partiçãop1.INSERT INTO range_tbl(serial_id, order_time) VALUES (20001, '2022-01-01'); -- Query OK, 1 row affected -
Tente inserir outra linha com o mesmo
serial_ideorder_time = '2022-01-02'. Ambas as linhas seriam direcionadas à partiçãop1, causando um conflito de chave única.INSERT INTO info_tbl(serial_id, order_time) VALUES (20001, '2022-01-02'); -- (1062, "ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'D25_000001_GROUP' ATOM 'dskey_d25_000001_group#polardbx-storage-1-master#11.167.60.147-1766#d25_000001': Duplicate entry '20001' for key 'serial_id' ") -
Insira uma linha com o mesmo
serial_ideorder_time = '2024-01-01'. Esta linha vai para a partiçãop3, então não há conflito — agora existem duas linhas comserial_id = 20001na tabela.INSERT INTO range_tbl(serial_id, order_time) VALUES (20001, '2024-01-01'); -- Query OK, 1 row affected SELECT * FROM range_tbl; -- +----+-----------+---------------------+ -- | id | serial_id | order_time | -- +----+-----------+---------------------+ -- | 2 | 20001 | 2024-01-01 00:00:00 | -- | 1 | 20001 | 2022-01-01 00:00:00 | -- +----+-----------+---------------------+ -- 2 rows in set
Exemplo 13: Operações DDL que movem dados entre partições podem falhar devido a erros de chave única duplicada
Ao alterar a política de particionamento de forma que linhas com valores duplicados de chave única sejam colocadas na mesma partição, o PolarDB-X reporta um conflito e a DDL falha.
Considerando a tabela range_tbl do Exemplo 12 (que já tem duas linhas com serial_id = 20001 nas partições p1 e p3), converter a tabela para uma tabela comum reuniria todas as linhas em um único local:
ALTER TABLE range_tbl SINGLE;
-- (4700, "ERR-CODE: [TDDL-4700][ERR_SERVER] server error by Failed to execute the DDL task. Caused by: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] Duplicated entry '200001' for key 'PRIMARY' ")
A DDL falha porque uma tabela comum exige unicidade em todas as linhas, condição violada pelos valores duplicados de serial_id.
Para prevenir isso, certifique-se de que os valores de chaves únicas locais não estejam duplicados antes de executar operações DDL que envolvam redistribuição de dados.
Caso uma tabela com chaves únicas locais já contenha valores duplicados, deduplique manualmente os dados de source antes de sincronizar com sistemas downstream para evitar conflitos de chave única.
FAQ
É necessária uma instrução especial para criar uma chave primária global ou uma chave única global?
Não. Utilize a sintaxe padrão do MySQL CREATE TABLE. O fato de a chave ser global ou local é determinado pela relação entre as colunas da chave e as colunas da chave de partição — não por nenhuma palavra-chave especial.
A tabela usa atualmente uma chave primária local. Como garantir chaves primárias globalmente únicas?
Use o recurso Sequence para gerar valores globalmente únicos. Atribua valores gerados por sequência à coluna de chave primária em vez de especificar valores manualmente.