As funções de índice bit-sliced (BSI) são extensões do Hologres que compactam dados de chave-valor em uma estrutura baseada em bitmap, permitindo agregação e filtragem de alto desempenho em grandes segmentos de usuários.
Como funciona
Um BSI compacta pares de chave-valor no formato cid::int, value::bigint. Cada valor decimal é convertido para binário e os dados binários são percorridos do bit menos significativo ao mais significativo. Para cada posição de bit, o roaring bitmap de todos os valores de cid cujo bit é 1 é registrado como um slice, formando a estrutura BSI.
Os dados de exemplo a seguir ilustram esse princípio:
|
cid |
Valor (decimal) |
Valor (binário) |
|
1 |
3 |
0011 |
|
2 |
6 |
0110 |
|
3 |
4 |
0100 |
|
4 |
10 |
1010 |
|
5 |
7 |
0111 |
|
6 |
NULL |
- |
O valor decimal máximo é 10, o que requer 4 bits. O BSI gerado a partir desses dados contém quatro slices:
slice 0: roaringbitmap
{1,5}slice 1: roaringbitmap
{1,2,4,5}slice 2: roaringbitmap
{2,3,5}slice 3: roaringbitmap
{4}
Cada BSI também armazena os seguintes metadados internos:
|
Campo |
Descrição |
Valor no exemplo |
|
|
Roaring bitmap de todos os valores de cid não NULL |
|
|
|
Valor máximo |
|
|
|
Valor mínimo |
|
|
|
Número de bits usados na representação binária |
|
Exemplos de cálculos para um público selecionado {1,3,5}:
Soma:
rb_and_cardinality(crowd, slice0) × 2<sup>0</sup>+ ... + rb_and_cardinality(crowd, slice3) × 2<sup>3</sup>= 14-
2 maiores valores:
crowd & slice3 = NULL crowd & slice2 = {3,5} -- top 2 values are {3,5} {3,5} & slice1 = {5} -- top 1 value is {5}
O BSI combina operações de conjunto de roaring bitmap com cálculos de valores, tornando-o eficiente para cenários de análise de perfil de usuário que utilizam tanto tags de atributo quanto tags de comportamento. Para um exemplo prático, consulte BSI (beta).
Limitações
Requisito de versão: Hologres V2.1 ou posterior. Para atualizar uma instância anterior, consulte Upgrade instances.
Value range: Cada valor em um BSI deve ser um inteiro de 1 a 2<sup>31</sup> − 1.
-
Extensões: Um superusuário precisa criar duas extensões no nível do banco de dados antes de usar o BSI. Crie cada extensão apenas uma vez por banco de dados.
ImportanteNão use
DROP EXTENSION <extension_name> CASCADE;. A opçãoCASCADEremove não apenas a extensão, mas também todos os objetos dependentes e seus dados, incluindo dados do PostGIS, dados de roaring bitmap, dados do Proxima, dados de log binário, dados de BSI, metadados, tabelas, visualizações e dados do servidor.-- Create extensions. Create roaring bitmaps before creating BSI. CREATE EXTENSION roaringbitmap; CREATE EXTENSION bsi; -- Drop the extensions. DROP EXTENSION bsi; DROP EXTENSION roaringbitmap;
Funções
Construtores BSI
bsi_build
Cria um BSI a partir de dois arrays unidimensionais paralelos.
Sintaxe
bsi_build(cids integer[], values bigint[]) → bsi
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
Array de valores de chave (cid) |
|
|
|
Array de valores correspondentes, alinhado com |
Retorno: bsi
Exemplo
SELECT bsi_iterate(bsi_build('{1,2,3}', '{2,4,6}'));
Saída:
{1,2}
{2,4}
{3,6}
bsi_add_value
Adiciona um único par de chave-valor a um BSI existente.
Sintaxe
bsi_add_value(b bsi, cid integer, value bigint) → bsi
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI existente |
|
|
|
A chave a ser adicionada |
|
|
|
O valor associado ao |
Retorno: bsi
Exemplo
SELECT bsi_iterate(bsi_add_value(bsi_build('{1,2,3}', '{2,4,6}'), 4, 8));
Saída:
{1,2}
{2,4}
{3,6}
{4,8}
Funções de expansão BSI
bsi_iterate
Expande um BSI em seus pares de chave-valor, retornando uma linha por par.
Sintaxe
bsi_iterate(b bsi) → set of integer[]
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI a ser expandido |
Retorno: set of integer[] — cada linha é {cid, value}
Exemplo
SELECT bsi_iterate(bsi_build('{1,2,3}', '{2,4,6}'));
Saída:
{1,2}
{2,4}
{3,6}
bsi_show
Retorna os primeiros N pares de chave-valor de um BSI como uma string de texto formatada.
Sintaxe
bsi_show(b bsi, n integer) → text
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI a ser inspecionado |
|
|
|
Número de pares de chave-valor a exibir |
Retorno: text — os primeiros N pares seguidos pela contagem dos pares restantes
Exemplo
SELECT bsi_show(bsi_build('{1,2,3}', '{2,4,6}'), 2);
Saída:
1=2,2=4...left 1
Funções de consulta BSI
As funções de comparação (bsi_eq, bsi_ge, bsi_gt, bsi_le, bsi_lt, bsi_neq, bsi_range) aceitam um parâmetro de filtro opcional do tipo bytea. Quando fornecido, a função primeiro faz a interseção do EBM do BSI com o bitmap de filtro e depois executa a comparação no subconjunto resultante.
bsi_ebm
Retorna o existence bitmap (EBM) de um BSI — o roaring bitmap de todos os valores de cid não NULL.
Sintaxe
bsi_ebm(b bsi) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_ebm(bsi_build('{1,2,3}', '{2,4,6}')));
Saída: {1,2,3}
bsi_filter
Retorna um novo BSI contendo apenas os valores de cid presentes tanto no EBM do BSI quanto no bitmap fornecido.
Sintaxe
bsi_filter(b bsi, crowd bytea) → bsi
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI de source |
|
|
|
Um roaring bitmap serializado como |
Retorno: bsi
Exemplo
SELECT bsi_iterate(bsi_filter(bsi_build('{1,2,3}', '{2,4,6}'), rb_build('{1,2}')));
Saída:
{1,2}
{2,4}
bsi_eq
Retorna os valores de cid cujo valor no BSI é igual ao limiar especificado.
Sintaxe
bsi_eq(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_eq(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {2,3}
bsi_neq
Retorna os valores de cid cujo valor no BSI é diferente do limiar especificado.
Sintaxe
bsi_neq(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_neq(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {1,4}
bsi_lt
Retorna os valores de cid cujo valor no BSI é menor que o limiar especificado.
Sintaxe
bsi_lt(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_lt(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {1}
bsi_le
Retorna os valores de cid cujo valor no BSI é menor ou igual ao limiar especificado.
Sintaxe
bsi_le(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_le(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {1,2,3}
bsi_gt
Retorna os valores de cid cujo valor no BSI é maior que o limiar especificado.
Sintaxe
bsi_gt(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_gt(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {4}
bsi_ge
Retorna os valores de cid cujo valor no BSI é maior ou igual ao limiar especificado.
Sintaxe
bsi_ge(b bsi, threshold bigint [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_ge(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 4));
Saída: {2,3,4}
bsi_range
Retorna os valores de cid cujo valor no BSI está entre os dois valores de limiar especificados.
Sintaxe
bsi_range(b bsi, lower bigint, upper bigint [, crowd bytea]) → roaringbitmap
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI de source |
|
|
|
Limite inferior do intervalo |
|
|
|
Limite superior do intervalo |
|
|
|
(Opcional) Roaring bitmap serializado para pré-filtrar o EBM |
Exemplo
SELECT rb_to_array(bsi_range(bsi_build('{1,2,3,4}', '{2,4,4,8}'), 3, 5));
Saída: {2,3}
bsi_compare
Função de comparação unificada que suporta todos os tipos de comparação por meio de um único ponto de entrada.
Sintaxe
bsi_compare(op text, b bsi [, crowd bytea], val1 bigint [, val2 bigint]) → roaringbitmap
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
Tipo de comparação: |
|
|
|
O BSI de source |
|
|
|
(Opcional) Roaring bitmap serializado para pré-filtrar o EBM |
|
|
|
O valor de comparação (limite inferior para |
|
|
|
(Obrigatório apenas para |
Exemplo
SELECT rb_to_array(bsi_compare('RANGE', bsi_build('{1,2,3,4}', '{2,4,4,8}'), 3, 5));
Saída: {2,3}
Funções analíticas e de agregação BSI
bsi_sum
Retorna a soma total dos valores do BSI e a contagem de valores de cid correspondentes (cardinalidade do EBM) como um array de dois elementos.
Sintaxe
bsi_sum(b bsi [, crowd bytea]) → bigint[]
Retorno: bigint[] — {sum, cardinality}
Exemplo
SELECT bsi_sum(bsi_build('{1,2,3,4}', '{2,4,6,8}'));
Saída: {20,4}
bsi_topk
Retorna os valores de cid que possuem os K maiores valores no BSI.
Sintaxe
bsi_topk(b bsi [, crowd bytea], k integer) → roaringbitmap
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
O BSI de source |
|
|
|
(Opcional) Roaring bitmap serializado para pré-filtrar o EBM |
|
|
|
Quantidade de maiores valores a retornar |
Exemplo
SELECT rb_to_array(bsi_topk(bsi_build('{1,2,3,4,5}', '{2,4,6,8,10}'), 3));
Saída: {3,4,5}
bsi_stat
Retorna a distribuição de valores de um BSI em intervalos definidos pelo usuário.
Sintaxe
bsi_stat(boundaries bigint[], b bsi [, crowd bytea]) → text
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
Array de valores de limite que definem os intervalos de distribuição |
|
|
|
O BSI de source |
|
|
|
(Opcional) Roaring bitmap serializado para pré-filtrar o EBM |
Retorno: text — faixas de intervalo com contagens, no formato (lower,upper]=count
Exemplo
SELECT bsi_stat('{1,3,5}', bsi_build('{1,2,3,4}', '{2,4,6,8}'));
Saída: (0,1]=0;(1,3]=1;(3,5]=1;(5,8]=2
bsi_add
Soma os valores de dois BSIs para os valores de cid compartilhados em seus EBMs e retorna um novo BSI.
Sintaxe
bsi_add(b1 bsi, b2 bsi) → bsi
Argumentos
|
Argumento |
Tipo |
Descrição |
|
|
|
Primeiro BSI |
|
|
|
Segundo BSI |
Exemplo
SELECT bsi_iterate(bsi_add(bsi_build('{1,2,3}', '{2,4,6}'), bsi_build('{1,2}', '{2,4}')));
Saída:
{1,4}
{2,8}
{3,6}
bsi_add_agg
Função de agregação que soma os valores de BSI em várias linhas.
Sintaxe
bsi_add_agg(b bsi) → bsi
Exemplo
SELECT bsi_iterate(bsi_add_agg(bsi_build('{1,2,3}', '{2,4,6}')));
Saída:
{1,2}
{2,4}
{3,6}
bsi_merge
Mescla dois BSIs cujos EBMs não têm sobreposição. Utilize esta função ao combinar partições de dados disjuntas.
Sintaxe
bsi_merge(b1 bsi, b2 bsi) → bsi
Exemplo
SELECT bsi_iterate(bsi_merge(bsi_build('{1,2}', '{2,4}'), bsi_build('{3,4}', '{6,8}')));
Saída:
{1,2}
{2,4}
{3,6}
{4,8}
bsi_merge_agg
Função de agregação que mescla várias linhas de BSI em uma só. Os BSIs de entrada devem ter EBMs sem sobreposição.
Sintaxe
bsi_merge_agg(b bsi) → bsi
Exemplo
SELECT bsi_iterate(bsi_merge_agg(bsi_build('{1,2,3}', '{2,4,6}')));
Saída:
{1,2}
{2,4}
{3,6}
bsi_transpose
Retorna o conjunto deduplicado de valores distintos no BSI como um roaring bitmap.
Sintaxe
bsi_transpose(b bsi [, crowd bytea]) → roaringbitmap
Exemplo
SELECT rb_to_array(bsi_transpose(bsi_build('{1,2,3,4,5}', '{2,4,4,8,8}')));
Saída: {2,4,8}
bsi_transpose_with_count
Retorna um novo BSI onde cada valor distinto é mapeado para o número de entradas de cid que possuem esse valor.
Sintaxe
bsi_transpose_with_count(b bsi [, crowd bytea]) → bsi
Exemplo
SELECT bsi_iterate(bsi_transpose_with_count(bsi_build('{1,2,3,4,5}', '{2,4,4,8,8}')));
Saída:
{2,1}
{4,2}
{8,2}
A saída {value, count} significa: o valor 2 aparece uma vez, o valor 4 aparece duas vezes e o valor 8 aparece duas vezes.
Próximos passos
BSI (beta) — exemplo completo de análise de perfil de usuário usando funções BSI