Estou usando o PostgreSQL 9.5 e estou tentando entender como implementar um índice GiST onde tenho uma representação que é uma versão compactada com perdas do tipo indexado. Por exemplo, digamos que eu tenha imagens armazenadas em BYTEA
type e, para o índice, armazeno os intervalos de cores (rmin, rmax, gmin, gmax, bmin, bmax) e desejo comparar imagens com base na semelhança de cores - por exemplo, com um ===
operador que retorna true quando as faixas de cores são exatamente iguais, me permitindo facilitar consultas como:
SELECT COUNT(*)
FROM icons, avatars
WHERE icon.image === avatar.image AND avatar.id = 123;
onde icons
e avatars
são ambas tabelas com um image
campo do tipo BYTEA
.
Depois de examinar a documentação de implementação, parece que isso deve ser possível. Usando a situação de exemplo acima, acho que poderia fazer o seguinte:
- o
union
método geraria o intervalo delimitador de todas as entradas picksplit
epenalty
apenas tentaria minimizar os intervalos, semelhante a um R-Treecompress
pegaria os dados BYTEA e calcularia a faixa de coresdecompress
seria uma função identidadeconsistent
(para o===
operador) retornaria verdadeiro se o intervalo de cores da entrada contivesse o intervalo de consulta para nós internos e somente se os intervalos correspondessem exatamente aos nós folha.
É este o caminho certo? Não estou claro sobre quando as etapas de compactação ocorrem. Por exemplo, consistent
é presumivelmente chamado várias vezes em diferentes nós da árvore. Então, isso significa que a consulta terá que recalcular o intervalo de cores dos dados da consulta todas as vezes? E no índice, os nós das folhas conterão uma cópia dos dados da imagem ou apenas sua faixa de cores?
Observação O exemplo fornecido é apenas para fins ilustrativos. Minha pergunta é sobre representações com perdas no GiST, não indexando imagens.
Como você já armazena os valores
(rmin, rmax, gmin, gmax, bmin, bmax)
para a coluna de imagem, um índice btree nessas coberturas verifica a igualdade perfeitamente:Esta consulta usará o índice:
Claro, você precisa de outro índice em
avatars.id
, ou possivelmente em(id, rmin, rmax, gmin, gmax, bmin, bmax)
para permitir varreduras somente de índice.Como Erwin disse, definir um índice gist personalizado para isso pode ser um exagero.
O último parágrafo da documentação a que você se refere informa como armazenar em cache o valor calculado, se desejar. Para um exemplo resolvido, veja o uso de fn_extra em contrib/pg_trgm/trgm_gist.c
Isso depende de como você implementa a função de compactação. A função tem acesso ao conhecimento se é chamada em uma entrada de folha ou em uma entrada não folha. Se você apenas compactar coisas em não-folhas, as folhas não serão compactadas. Portanto, cabe a você.