Geralmente descrevemos o Couchbase Server como um banco de dados de documentos. Essa é uma boa descrição: O Couchbase tem um desempenho excelente como um armazenamento de documentos JSON.
Ao modelar nossos dados para o Couchbase Server, no entanto, pode ser útil pensar nele mais como um armazenamento de valores-chave.
Pensamento de valor-chave versus pensamento de documento
Então, qual é a diferença prática entre os armazenamentos de valores-chave e os armazenamentos de documentos? Principalmente, trata-se de como você consulta os dados.
Os bancos de dados de valores-chave tendem a armazenar dados como unidades opacas, fornecendo um índice: a própria chave. Você armazena e recupera dados como partes discretas usando apenas a chave. Isso geralmente é rápido porque é descomplicado, mas também é uma ferramenta bastante simples.
Os armazenamentos de documentos, por outro lado, fornecem índices adicionais sobre os dados dentro do documento e, portanto, você tem muito mais liberdade para consultar esses dados. É claro que a consulta em qualquer sistema de banco de dados tem um custo de recursos.
Ao projetar nosso modelo de dados, precisamos escolher a abordagem a ser adotada. Para fazer isso, precisamos entender as vantagens e desvantagens.
As vantagens e desvantagens
O Couchbase está igualmente à vontade para fornecer acesso a valores-chave e acesso aos seus dados no estilo de consulta de documentos.
Ambas as abordagens têm suas vantagens e desvantagens:
| Vantagens do acesso a valores-chave | Vantagens do acesso em estilo de documento |
|---|---|
| Super-rápido: respostas abaixo de milissegundos | Flexibilidade: crie facilmente novos índices a qualquer momento |
| Imediatamente consistente dentro do cluster |
Insight: crie exibições que lidem com dados variáveis e que possam fornecer insight analítico em vez de apenas outro índice |
| Pequeno impacto nos recursos | Veja dentro do documento: crie índices em pares KV dentro de seu JSON |
Com as visualizações do Couchbase hoje e em breve N1QLA consulta no Couchbase oferece uma enorme flexibilidade. Quando o N1QL estiver disponível de modo geral e a indexação for compatível com ele, talvez grande parte deste blog se torne obsoleta.
No entanto, no momento, podemos manter todos os benefícios do modelo de valor-chave do Couchbase - consistência imediata, tempos de resposta em cache de menos de milissegundos, perfil de escalonamento linear etc. - sem abrir mão de muita flexibilidade de consulta. A maneira de fazer isso é criar índices secundários manuais.
O que importa é a pesquisa
Imagine que estamos armazenando perfis de usuários no Couchbase. A primeira escolha que precisamos fazer é como digitá-los.
Digamos que nossos usuários façam login em nosso sistema usando seu endereço de e-mail. Isso significa que, no mínimo, quando alguém faz login, sabemos uma coisa sobre ele. Se digitarmos nossos perfis de usuário por endereço de e-mail, teremos um processo de login mais ou menos assim:
- O usuário insere seu endereço de e-mail (por exemplo, lily@example.com) e a senha no formulário de login.
- Obtemos o documento do Couchbase que tem a chave lily@couchbase.com
- Verificamos a senha em relação ao hash no perfil do usuário.
- Se for bem-sucedido, concluímos o login e a Lily continua com seus afazeres.
Ótimo, isso foi fácil.
Depois de algum tempo, Lily muda seu endereço de e-mail e quer atualizá-lo em nosso sistema. Naturalmente, ela desejará usar seu endereço de e-mail atualizado para fazer login.
Temos três opções de como lidar com isso:
- crie um documento de perfil de usuário totalmente novo, com o novo endereço de e-mail como chave, e destrua o antigo
- criar um documento de redirecionamento
- desde o início, use documentos de pesquisa para criar um índice secundário manual.
A primeira opção parece um pouco deselegante. Por exemplo, se estivéssemos nos referindo ao documento em outra parte do nosso sistema, essas referências seriam agora becos sem saída.
Redirecionamentos
Em vez disso, poderíamos usar a segunda opção e criar um novo documento com a chave do novo endereço de e-mail. O conteúdo do documento seria simplesmente o endereço de e-mail antigo. Obviamente, também precisaríamos colocar o novo endereço de e-mail dentro do próprio documento de perfil do usuário para que não precisássemos do documento de pesquisa para associar esse endereço de e-mail a esse usuário.
Agora, nosso processo de login terá a seguinte aparência:
- O usuário insere seu endereço de e-mail (por exemplo, lily@newdomain.com) e a senha no formulário de login.
- Obtemos o documento do Couchbase que tem a chave lily@newdomain.com.
- Vemos que o documento é outro endereço de e-mail (lily@example.com), em vez de um perfil de usuário completo.
- Obtemos o documento lily@example.com.
- Verificamos a senha em relação ao hash no perfil do usuário.
- Se for bem-sucedido, concluímos o login e a Lily continua com seus afazeres.
Isso pode funcionar. No entanto, isso nos traz uma pequena complicação: não sabemos mais o que receberemos quando fizermos um GET em um endereço de e-mail.
Em vez disso, poderíamos começar a usar documentos de pesquisa desde o início.
Uso de um índice secundário manual
É bem provável que uma parte da nossa base de usuários mude de endereço de e-mail durante a vida útil da conta. Portanto, faz sentido lidarmos com essa probabilidade desde o início.
Em vez de digitar os documentos de perfil dos nossos usuários com seus endereços de e-mail, devemos digitá-los com outra coisa exclusiva que permanecerá constante. Como estamos procurando algo imutável, o ideal é que a chave em si não esteja relacionada a nada sobre os próprios usuários. O Couchbase Server nos oferece uma maneira fácil de lidar com isso: contadores atômicos.
Podemos chamar contadores atômicos com um incremento ou um decremento, mais um valor, e então recebemos o número resultante de volta. Se incrementarmos o contador em um a cada vez que criarmos um novo perfil de usuário, isso nos dará uma chave exclusiva e imutável.
Vamos dar uma olhada em como isso funciona:
- Nosso usuário conclui o processo de inscrição.
- Incrementamos o contador e ele nos devolve 1001.
- Criamos nosso documento de perfil de usuário usando a chave 1001.
Agora, as alterações no perfil do usuário não afetam a chave. No entanto, há um problema: a menos que queiramos fazer com que nossos usuários memorizem um nome de usuário numérico, como 1001, teremos que encontrar outra maneira de combinar um nome de usuário amigável com o perfil do usuário.
É aí que entra o nosso índice secundário manual. Vamos adicionar outra etapa ao nosso processo de registro:
- Criamos um documento de pesquisa com chave no endereço de e-mail do usuário, com um valor de 1001.
Agora, nosso processo de login tem a seguinte aparência:
- O usuário insere seu endereço de e-mail (por exemplo, lily@newdomain.com) e a senha no formulário de login.
- Obtemos o documento do Couchbase que tem a chave lily@newdomain.com.
- Vemos que o valor desse documento é 1001, portanto, GETamos o documento do perfil do usuário com a chave 1001.
- Verificamos a senha em relação ao hash no perfil do usuário.
- Se for bem-sucedido, concluímos o login e a Lily continua com seus afazeres.
Com a maioria dos sistemas de banco de dados, isso poderia introduzir um atraso inaceitável, mas com o Couchbase a pesquisa adicional deve ser inferior a um milissegundo. Isso abre uma gama completa de outros índices manuais que poderíamos introduzir: Identificadores do Twitter, números de telefone, cidades e assim por diante.
É claro que isso introduz um pouco mais de trabalho na camada do aplicativo, mas, em troca, obtemos a flexibilidade dos índices secundários e, ao mesmo tempo, mantemos toda a velocidade e a escalabilidade que nos fizeram escolher o Couchbase Server em primeiro lugar.
Na próxima vez, examinarei a nomeação de chaves.
Como podemos criar um índice secundário usando java/scala?
Se eu aplicar o índice secundário no e-mail usando o comando abaixo:
CREATE INDEX emailadd ON
usuário-acc(e-mail);Como posso obter o documento para um endereço de e-mail?
Você poderia escrever aqui um exemplo de consulta que eu possa executar sobre o índice secundário?
Olá, você precisa usar em sua consulta antes do WHERE
Assim: por exemplo, aqui eu uso id_ix (índice de id), que foi criado usando o GSI. Você também pode simplesmente usar seu nome e o tipo de índice :)
USE INDEX (
id_ixUSANDO GSI)Espero que isso ajude
Olá, você precisa usar em sua consulta antes do WHERE
Assim: por exemplo, aqui eu uso id_ix (índice de id), que foi criado usando o GSI. Você também pode simplesmente usar seu nome e o tipo de índice :)
USE INDEX (
id_ixUSANDO GSI)