A extensão sequential_uuid oferece dois geradores de UUID que criam padrões sequenciais. Isso ajuda a reduzir os problemas de E/S aleatória causados por UUIDs totalmente aleatórios.
Aplicabilidade
O PolarDB for PostgreSQL suporta as seguintes versões:
PostgreSQL 18 (versão secundária do mecanismo 2.0.18.1.2.0 e posterior)
PostgreSQL 17 (versão secundária do mecanismo 2.0.17.6.4.0 e posterior)
PostgreSQL 16 (versão secundária do mecanismo 2.0.16.9.9.0 e posterior)
PostgreSQL 15 (versão secundária do mecanismo 2.0.15.14.6.0 e posterior)
PostgreSQL 14 (versão secundária do mecanismo 2.0.14.5.1.0 e posterior)
PostgreSQL 11 (versão secundária do mecanismo 2.0.11.9.28.0 e posterior)
Visualize o número da versão secundária do mecanismo no console ou execute a instrução SHOW polardb_version;. Se a versão secundária do mecanismo não atender ao requisito, atualize a versão secundária do mecanismo.
Informações básicas
Os geradores padrão de UUID aleatório selecionam valores uniformemente dentro de um intervalo definido. Essa abordagem resulta em baixa localidade de dados durante a inserção em um índice, pois todas as páginas folha do índice têm a mesma probabilidade de acesso. Consequentemente, o índice inteiro pode ser forçado a permanecer na memória. Embora isso não seja um problema para índices pequenos, a taxa de acerto no cache cai rapidamente quando o tamanho do índice excede a capacidade do buffer compartilhado ou da RAM.
Diferentemente dos UUIDs aleatórios, aqueles baseados em sequências e timestamps apresentam um padrão sequencial. Esse padrão garante que novos dados sejam quase sempre inseridos na extremidade mais à direita do índice, já que os novos valores de sequência são maiores que os anteriores e os timestamps aumentam monotonicamente. Tal comportamento contribui para melhorar a taxa de acerto no cache.
Geradores de UUID com padrões sequenciais aumentam a previsibilidade dos UUIDs e a probabilidade de colisões entre máquinas.
Para obter mais informações sobre os benefícios dos UUIDs sequenciais, consulte Sequential UUID Generators.
O objetivo principal do sequential_uuid é gerar UUIDs mais sequenciais sem reduzir significativamente a aleatoriedade. A redução da aleatoriedade pode aumentar a probabilidade de colisões e a previsibilidade dos UUIDs.
Design do gerador
A maneira mais simples de tornar os UUIDs mais sequenciais é usar um valor sequencial como prefixo. Por exemplo, é possível obter um valor de uma sequência ou timestamp e anexar dados aleatórios para formar um UUID de 16 bytes. Esse método produz UUIDs quase completamente sequenciais, mas apresenta dois problemas:
Redução da aleatoriedade: ao utilizar uma sequência que gera valores
bigint, a parte aleatória do UUID diminui de 16 bytes para 8 bytes. Os timestamps reduzem a aleatoriedade de forma semelhante, dependendo de sua precisão. Essa diminuição eleva a probabilidade de colisões e a previsibilidade dos UUIDs. É possível, por exemplo, determinar quais UUIDs foram gerados próximos temporalmente e até mesmo inferir o timestamp específico.Inchaço: se os valores aumentarem monotonicamente, o índice poderá ficar inchado após a exclusão de dados históricos. Um índice baseado em timestamp em uma tabela de log é um exemplo comum dessa situação.
Para resolver esses problemas, os geradores sequential_uuid foram projetados para reiniciar ciclicamente de forma periódica. Esse retorno cíclico pode ocorrer após a geração de um número definido de UUIDs ou depois de um intervalo de tempo específico. Em ambos os casos, os UUIDs são gerados em blocos com o formato (ID do bloco; dados aleatórios). O tamanho do ID do bloco é fixo e depende do número de blocos, que é um parâmetro do gerador. Por exemplo, ao usar o padrão de 65.536 blocos, o ID do bloco requer 2 bytes. O ID do bloco aumenta a cada novo bloco e eventualmente retorna ao início.
-
O gerador de UUID baseado em sequência pode usar blocos contendo 256 UUIDs cada. O ID do bloco de 2 bytes é calculado da seguinte forma:
(nextval('s') / 256) % 65536NotaO gerador reinicia ciclicamente a cada 16.777.216 (256 × 65.536) UUIDs gerados.
O tamanho do bloco é definido pela quantidade de UUIDs que ele contém.
-
O gerador de UUID baseado em timestamp possui um padrão de 65.536 blocos, assim como o gerador baseado em sequência. O ID do bloco é calculado conforme abaixo:
(timestamp / 60) % 65536NotaO ciclo do gerador se reinicia aproximadamente a cada 45 dias.
O tamanho do bloco corresponde a um intervalo de tempo. O valor padrão é 60 segundos.
Funções de geração de UUID
A extensão sequential_uuid fornece duas funções para gerar UUIDs com padrões sequenciais. Uma função utiliza uma sequência, enquanto a outra emprega um timestamp.
-
A função uuid_sequence_nextval aceita os seguintes parâmetros:
Um objeto de sequência do tipo
regclass.Tamanho do bloco como um número inteiro. O valor padrão é 65536.
Número inteiro representando a quantidade de blocos (padrão: 65536).
Crie um UUID com padrão sequencial usando uma sequência:
CREATE EXTENSION sequential_uuids; CREATE SEQUENCE s; SELECT uuid_sequence_nextval('s'::regclass, 256, 65536);Resultado:
uuid_sequence_nextval -------------------------------------- 00005547-8a67-452d-bdf7-b390f1edc49b (1 row) -
A função uuid_time_nextval aceita os seguintes parâmetros:
Intervalo de tempo em segundos como um número inteiro (padrão: 60).
Quantidade de blocos como um número inteiro (padrão: 65536).
Crie um UUID com padrão sequencial usando um timestamp:
CREATE EXTENSION sequential_uuids; SELECT uuid_time_nextval(1, 256);Resultado:
uuid_time_nextval -------------------------------------- 08dac705-8776-4ce3-a45c-123fd65e11e8 (1 row)
Os valores padrão desses parâmetros são adequados para a maioria dos cenários.