Estou curioso sobre esses dois índices secundários e as diferenças entre eles. É difícil imaginar como isso se parece. E eu acho que isso ajudará mais pessoas do que apenas eu.
Estou curioso sobre esses dois índices secundários e as diferenças entre eles. É difícil imaginar como isso se parece. E eu acho que isso ajudará mais pessoas do que apenas eu.
Respostas:
Os índices secundários locais ainda dependem da chave hash original. Ao fornecer uma tabela com hash + range, pense no LSI como hash + range1, hash + range2 .. hash + range6. Você recebe mais 5 atributos de intervalo para consulta. Além disso, existe apenas uma taxa de transferência provisionada.
Os índices secundários globais definem um novo paradigma - diferentes chaves de hash / intervalo por índice.
Isso interrompe o uso original de uma chave de hash por tabela. É também por isso que, ao definir o GSI, é necessário adicionar um rendimento provisionado por índice e pagar por ele.
Informações mais detalhadas sobre as diferenças podem ser encontradas no anúncio do GSI
Aqui está a definição formal da documentação:
Índice secundário global - um índice com uma chave de hash e intervalo que pode ser diferente da tabela. Um índice secundário global é considerado "global" porque as consultas no índice podem abranger todos os dados em uma tabela, em todas as partições.
Índice secundário local - um índice que possui a mesma chave de hash da tabela, mas uma chave de intervalo diferente. Um índice secundário local é "local" no sentido de que todas as partições de um índice secundário local têm o escopo definido para uma partição de tabela que possui a mesma chave de hash.
No entanto, as diferenças vão muito além das possibilidades em termos de definições-chave. Abaixo, alguns fatores importantes que impactarão diretamente o custo e o esforço para manter os índices:
Os índices secundários locais consomem a taxa de transferência da tabela. Quando você consulta registros por meio do índice local, a operação consome unidades de capacidade de leitura da tabela. Quando você executa uma operação de gravação (criar, atualizar, excluir) em uma tabela que possui um índice local, haverá duas operações de gravação, uma para a tabela e outra para o índice. Ambas as operações consumirão unidades de capacidade de gravação da tabela.
Os índices secundários globais têm sua própria taxa de transferência provisionada; quando você consulta o índice, a operação consome capacidade de leitura do índice; quando você executa uma operação de gravação (criar, atualizar, excluir) em uma tabela que possui um índice global, haverá dois operações de gravação, uma para a tabela e outra para o índice *.
* Ao definir a taxa de transferência provisionada para o Índice Secundário Global, preste atenção especial aos seguintes requisitos:
Para que uma gravação de tabela seja bem-sucedida, as configurações de taxa de transferência provisionada para a tabela e todos os seus índices secundários globais devem ter capacidade de gravação suficiente para acomodar a gravação; caso contrário, a gravação na tabela será regulada.
Os índices secundários locais só podem ser criados quando você está criando a tabela; não há como adicionar o índice secundário local a uma tabela existente; também, depois de criar o índice, você não pode excluí-lo.
Os índices secundários globais podem ser criados quando você cria a tabela e é adicionado a uma tabela existente, a exclusão de um índice secundário global existente também é permitida.
Os índices secundários locais suportam consistência eventual ou forte, enquanto o índice secundário global suporta apenas consistência eventual.
Os índices secundários locais permitem recuperar atributos que não são projetados para o índice (embora com custo adicional: desempenho e unidades de capacidade consumida). Com o Índice Secundário Global, você pode recuperar apenas os atributos projetados no índice.
Consideração especial sobre a exclusividade das chaves definidas para índices secundários:
Em um Índice Secundário Local, o valor da chave do intervalo NÃO precisa ser exclusivo para um determinado valor da chave de hash, o mesmo se aplica aos Índices Secundários Globais, os valores da chave (Hash e Intervalo) NÃO precisam ser exclusivos.
Fonte: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html
Estas são as possíveis pesquisas por índice:
Índices Hash e Range de uma tabela: estes são os índices habituais das versões anteriores do Amazon AWS SDK.
Índices globais e locais: são índices 'adicionais' criados em uma tabela, além dos índices de hash e intervalo existentes da tabela. O índice global é semelhante a um hash. O índice de intervalo se comporta de maneira semelhante ao índice de intervalo usado com o hash da tabela. No seu modelo de entidade em seu código, o getter deve ser anotado desta maneira:
Para índices globais:
@DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
@DynamoDBAttribute(attributeName = PROPERTY_USER)
public String getUser() {
return user;
}
Para o índice de intervalo associado ao índice global:
@DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
@DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP)
public String getTimestamp() {
return timestamp;
}
Além disso, se você ler uma tabela por um índice Global, ela deverá ser uma leitura Eventual (não leitura consistente):
queryExpression.setConsistentRead(false);
Uma maneira de colocar isso é o seguinte:
LSI - permite executar uma consulta em uma única Hash-Key enquanto usa vários atributos diferentes para "filtrar" ou restringir a consulta.
GSI - permite executar consultas em várias chaves de hash em uma tabela, mas, como resultado, resulta em custos adicionais na taxa de transferência.
Uma análise mais abrangente dos tipos de tabela e como eles funcionam, abaixo:
Apenas hash
Como você provavelmente já sabe; uma Hash-Key por si só deve ser exclusiva, pois a gravação em uma Hash-Key que já existe substituirá os dados existentes.
Hash + Range
Uma Hash-Key + Range-Key permite que você tenha várias teclas Hash iguais, desde que tenham uma tecla de intervalo diferente. Nesse caso, se você gravar em uma Hash-Key que já existe, mas usar uma Range-Key que ainda não é usada por essa Hash-Key, ela criará um novo item, enquanto que se um item com a mesma combinação Hash + Range já existe, substitui o item correspondente.
Outra maneira de pensar sobre isso é como um arquivo com um formato. Você pode ter um arquivo com o mesmo nome (hash) que outro, na mesma pasta (tabela), desde que o formato (intervalo) seja diferente. Da mesma forma, você pode ter vários arquivos do mesmo formato, desde que o nome seja diferente.
LSI
Um LSI é basicamente o mesmo que Hash-Key + Range-Key e segue as mesmas regras que ele, ao criar itens, exceto que você também deve fornecer valores para os LSIs; eles não podem ser deixados vazios / nulos.
Dizer que um LSI é "Range-Key 2" não está totalmente correto, pois você não pode ter (usando meu arquivo e formatar a analogia anteriormente) um arquivo chamado: file.format.lsi
e file.format.lsi2
. Você pode, no entanto, ter file.format.lsi
e file.format2.lsi
ou file.format.lsi
e file2.format.lsi
.
Basicamente, um LSI é apenas uma "chave de filtro", não uma chave de intervalo real; sua combinação básica de valores Hash e Intervalo ainda deve ser única, enquanto os valores LSI não precisam ser únicos. Uma maneira mais fácil de ver isso é pensar no LSI como dados nos arquivos. Você pode escrever um código que encontre todos os arquivos com o nome "PROJECT101", independentemente deles fileFormat
, e depois leia os dados para determinar o que deve ser incluído na consulta e o que é omitido. É basicamente assim que o LSI funciona (apenas sem a sobrecarga extra de abrir o arquivo para ler seu conteúdo).
GSI
Para o GSI, você está essencialmente criando outra tabela para cada GSI, mas sem o incômodo de manter várias tabelas separadas que espelham dados entre eles; é por isso que eles custam mais rendimento.
Portanto, para um GSI, você pode especificar fileName
como Hash-Key fileFormat
base e como Range-Key base. Em seguida, você pode especificar um GSI que possua uma Hash-Key fileName2
e uma Range-Key of fileFormat2
. Você pode consultar em um fileName
oufileName2
se quiser, ao contrário do LSI, onde você pode apenas consultar fileName
.
As principais vantagens são que você só precisa manter uma tabela, em vez de 2, e sempre que gravar no Hash / Range primário ou no GSI Hash / Range (s), os outros também serão atualizados automaticamente, então você não pode "esquecer" de atualizar as outras tabelas como você pode com uma configuração de várias tabelas. Além disso, não há chance de uma conexão perdida após a atualização de uma e antes da atualização da outra, como ocorre na configuração de várias tabelas.
Além disso, um GSI pode "sobrepor" a combinação básica Hash / Range. Então, se você quiser fazer uma mesa com fileName
e fileFormat
como base Hash / Range filePriority
efileName
como seu GSI, você pode.
Por fim, uma combinação GSI Hash + Range não precisa ser única, enquanto a combinação base Hash + Range precisa ser única. Isso é algo que não é possível com uma configuração de mesa dupla / múltipla, mas é com GSI. Como resultado, você DEVE fornecer valores para a base e o GSI Hash + Range, ao atualizar; nenhum desses valores pode ser vazio / nulo.
Outra maneira de explicar: o LSI ajuda você a fazer consultas adicionais sobre itens com a mesma chave Hash. O GSI ajuda você a fazer consultas semelhantes nos itens "do outro lado da mesa". Tão muito útil.
Se você possui uma tabela de perfil de usuário: ID exclusivo, nome, email. Aqui, se você precisar tornar a tabela consultável em nome, email - a única maneira é torná-las GSI (o LSI não ajudará)
Esta documentação fornece uma boa explicação:
https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/
Não pude comentar esta questão, mas qual é melhor em termos de desempenho de gravação e leitura:
(Índice local com taxa de transferência de leitura e gravação de tabela de 100) ou (Índice global com taxa de transferência de leitura / gravação de 50 junto com taxa de transferência de leitura / gravação de tabela de 50?)
Não preciso de chave de partição separada para o meu caso de uso, portanto, o índice local deve ser suficiente para a funcionalidade necessária.
GSIs não podem ser usados para leituras consistentes.
Os LSIs podem ser usados para leituras consistentes, mas limitarão o tamanho da partição principal a 10 GB. Também os LSIs podem ser criados apenas na criação da tabela.