Vou precisar de algumas consultas no formulário "list all objects onde um dos altnames é 'foobar'." O tamanho esperado da tabela é da ordem de alguns milhões de registros. As consultas JSON do Postgres podem ser usadas para isso e também podem ser indexadas (Índice para encontrar o elemento na matriz JSON, por exemplo). No entanto, DEVE ser feito dessa maneira ou é uma solução perversa que não é recomendada?
Ele pode ser feito dessa forma, mas isso não significa que você deve. De certa forma, a melhor prática já está bem documentada (veja, por exemplo, usando hstore vs usando XML vs usando EAV vs usando uma tabela separada) com um novo tipo de dados que, para todos os efeitos e propósitos práticos (além de validação e sintaxe), não é diferente de opções anteriores não estruturadas ou semiestruturadas.
Dito de outra forma, é o mesmo porco velho com maquiagem nova.
O JSON oferece a capacidade de usar índices de árvore de pesquisa invertida , da mesma forma que hstore, array types e tsvectors fazem. Eles funcionam bem, mas lembre-se de que são projetados principalmente para extrair pontos em uma vizinhança (pense em tipos de geometria) ordenados por distância, em vez de extrair uma lista de valores em ordem lexicográfica.
Para ilustrar, tome os dois planos que a resposta de Roman descreve:
- Aquele que faz uma varredura de índice percorre as páginas do disco diretamente, recuperando as linhas na ordem indicada pelo índice.
- Aquele que faz uma varredura de índice de bitmap começa identificando todas as páginas do disco que podem conter uma linha e as lê conforme aparecem no disco, como se estivesse (e, de fato, exatamente como) fazendo uma varredura de sequência que pula áreas inúteis.
Voltando à sua pergunta:índices de árvore invertida desordenados e superdimensionados realmente melhorará o desempenho do seu aplicativo se você usar tabelas Postgres como lojas JSON gigantes. Mas eles também não são uma bala de prata e não o levarão até o design relacional adequado ao lidar com gargalos.
O resultado final, no final, não é diferente do que você obteria ao decidir usar hstore ou um EAV:
- Se ele precisar de um índice (ou seja, aparecer com frequência em uma cláusula where ou, ainda mais importante, em uma cláusula join), você provavelmente desejará os dados em um campo separado.
- Se for principalmente cosmético, JSON/hstore/EAV/XML/whatever-makes-you-sleep-at-night funciona bem.