Praticamente todas as organizações precisam registrar e recuperar dados de usuários. Frequentemente, esses dados de usuário são permanentes, como contas de usuário com configurações, históricos e preferências definidos. Com a mesma frequência, os dados são transitórios, como no caso de sessões anônimas com apenas atividades recentes. Em ambos os casos, a organização precisará de um armazenamento de perfil de usuário/armazenamento de sessão para persistir e consultar os dados. Como esse tipo de dados é a base de muitos aplicativos na maioria das organizações, é imprescindível que o design do banco de dados de perfil de usuário seja eficiente, disponível e dimensionável. Esta postagem sobre como armazenar as preferências do usuário no banco de dados explora esse sistema.
Examinaremos um serviço de armazenamento de perfil (API REST) utilizando o Couchbase como banco de dados com um modelo de dados de usuário que aproveita os pontos fortes do Couchbase. Começaremos com todos os dados em um documento. Em seguida, veremos como e por que podemos normalizar esse documento em documentos separados e a lógica por trás das alterações. Tudo isso na perspectiva do que funcionará melhor para o modelo de dados de perfil de usuário e como planejamos utilizar os recursos do Couchbase Server.
Definição do serviço de perfil de usuário
Vamos começar definindo o serviço de exemplo e seus parâmetros. Aqui estão os parâmetros de design que me dei para este projeto:
- Ele deve ser o armazenamento de perfil autorizado para todos os microsserviços voltados para o cliente de uma empresa fictícia e expor uma API REST para dar suporte a operações CRUD nos dados.
- A API deve ser versionada com a funcionalidade mantida e obsoleta de acordo com o documento de design.
- A meta de tempo de atividade é 99,999% ou melhor.
- Ser capaz de definir perfis de usuário a serem mantidos por X anos após o último login e, de preferência, o banco de dados deve gerenciar a exclusão dos dados da conta em conjunto com o aplicativo que define o tempo de vida (TTL) nos objetos de cada usuário.
- O serviço deve ser capaz de executar um mínimo de 50.000 autenticações e 10.000 pesquisas de perfil de usuário principal por segundo em instâncias do AWS de tamanho relativamente modesto.
Definição dos serviços expostos pela API REST
É necessário começar mapeando como os dados serão usados. As interfaces que meu serviço exporá e quais serão as mais e as menos usadas. Isso me ajudará a definir a melhor forma de projetar meus documentos. O Couchbase me permite projetar um esquema de documento com base em como, quando e com que frequência o aplicativo usará os dados, e não em como o banco de dados os armazenará, como você pode ser forçado a fazer em um RDBMS.
Aqui estão alguns exemplos de métodos que alguém pode ter para esse serviço. Não vou listar todos eles e perder tempo, mas você já entendeu a ideia.
- getUserProfile(userID) - obtém todos os objetos no banco de dados para o usuário. Ele lerá uma matriz do nome do objeto do padrão de chave estabelecido (por exemplo, ) e, em seguida, fará uma operação de obtenção em massa de todos os objetos do usuário.
- getSecurityQuestions(userID) - Verifica no documento de informações de login se o usuário está habilitado e, se estiver, retorna o documento de perguntas de segurança do usuário. Se o usuário estiver desativado, ele retornará um erro.
- setSecurityQuestions(userID) - grava o documento de perguntas de segurança do usuário.
- authorizeUser(userID, passwordHash, IP) - obtém o documento de autenticação do usuário, chama a função isEnabled e, se a conta estiver ativada, verifica se a senha corresponde. Se corresponder, ele atualiza o documento com o IP e o último login.
- isEnabled(userID) - verifica o documento de informações de login do usuário para ver se a conta está ativada ou não no sistema. Ele retornará verdadeiro ou falso.
Procure uma lista completa dos métodos na postagem posterior do blog que discute o desenvolvimento do aplicativo e o código de amostra.
O documento inicial do usuário principal
Aqui está um exemplo de um documento de perfil de usuário com o qual eu poderia começar a capturar todos os dados de que meu serviço precisará, e essa seria uma maneira perfeitamente válida de fazer isso.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
chave : hernandez94 { "nome de usuário" : "hernandez94", "firstName" : "Jennifer", "middleName" : "Maria", "lastName" : "Hernandez", "endereços" : [ { "tipo" : "casa", "addr1" : "1929 Crisanto Ave", "endereço" : "Apt 123", "addr3" : "c/o J. Hernandez", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94040" }, { "tipo" : "trabalho", "addr1" : "2700 W El Camino Real", "addr2" : "Suíte #123", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94040" }, { "tipo" : "faturamento", "addr1" : "P.O. Box 123456", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94041" } ], "e-mails" : [ { "tipo" : "trabalho", "addr" : "work@email.com" }, { "tipo" : "pessoal", "addr" : "personal@email.com", "primário" : verdadeiro } ], "telefones" : [ { "tipo" : "trabalho", "num" : "+12345678900" }, { "tipo" : "móvel", "num" : "+12345678901" } ], "createdate" : "2016-08-01 15:03:40", "lastlogin": "2016-08-01 17:03:40", "pword": "app-hashed-password", "loc": "IP ou fqdn", "habilitado" : verdadeiro, "sec-questions" : [ { "question1" : "A pergunta de segurança 1 vai para aqui", "resposta" : "A resposta à pergunta de segurança 1 fica aqui" }, { "question2" : "A pergunta de segurança 2 fica aqui", "resposta" : "A resposta à pergunta de segurança 2 fica aqui" }, { "question3" : "A pergunta de segurança 3 fica aqui", "resposta" : "A resposta à pergunta de segurança 3 fica aqui" } ], "sec-roles" : [101, 301, 345], "doc-type" : "usuário" } |
Esse documento tem cerca de 1,41kb e todos os dados ainda não estão totalmente preenchidos. Portanto, esse documento pode ficar maior dependendo do usuário. Se você tiver desenvolvedores ou for um desenvolvedor que gosta de adicionar, adicionar e adicionar dados a um documento ou tabela, ele poderá crescer muito com a evolução do seu aplicativo/serviço. Vamos dar uma olhada na otimização desse documento para saber como e quando o aplicativo usará esses dados.
Uma rápida palavra sobre acesso a dados no Couchbase
Para as partes principais desse serviço, preciso do poder e do desempenho de acessar meus dados por meio de uma chave e consultar os dados o mínimo possível. Sem repetir minha outra postagem no blog sobre acesso a dados Se você não quiser usar o Couchbase em demasia, o Couchbase tem várias maneiras de obter os dados. Se você fornecer o ObjectID do(s) objeto(s) desejado(s), seu aplicativo poderá ler e gravar esses objetos de forma excepcionalmente rápida no cache gerenciado do Data Service.
Se você quiser fazer uma consulta usando a linguagem N1QL do Couchbase (~98% compatível com ANSI 92 SQL), isso significa que você tem uma pergunta sobre os dados e isso também pode ser feito por meio do Query Service. Por sua natureza de ter que fazer mais trabalho, a consulta tem menos desempenho do que trabalhar com dados por ObjectID. É a diferença entre ter uma pergunta (consulta) e já saber a resposta (ObjectID). (Para obter mais informações sobre por que digo isso, consulte minha outra postagem no blog sobre "Como as necessidades funcionais e de desempenho determinam o acesso aos dados no Couchbase“).
Para esse projeto de esquema de banco de dados de perfil de usuário, garantiremos que nossos objetos possam ser acessados com eficiência por ambos os meios, quando necessário. Os "caminhos quentes" do aplicativo serão acessados pelo ObjectID o máximo possível, mas também faremos consultas onde isso for necessário. Temos que atender aos requisitos estabelecidos acima neste documento.
Otimização do documento principal do usuário
Ao projetar um modelo de dados do usuário para esse serviço, temos algumas opções disponíveis que são, de certa forma, exclusivas do Couchbase e de como ele dimensiona, executa e gerencia a memória. Como todos os objetos estão qualificados para serem mantidos no cache gerenciado do serviço de dados, queremos que o modelo de dados do documento e o padrão de chave usados pelo nosso serviço sejam flexíveis o suficiente para que os dados de que precisamos com frequência estejam no cache gerenciado e os dados usados com pouca frequência possam estar apenas no disco, o que não é problema. Outros bancos de dados de documentos NoSQL podem fazer com que você coloque tudo em um documento e depois consulte esses dados. A consulta com N1QL também está disponível no Couchbase, e nós a usaremos para fins específicos. Mais uma vez, a arquitetura do Couchbase, com seu modelo de dados flexível e cache gerenciado integrado, nos dá a capacidade de escolher onde e como queremos utilizar esse poder a nosso favor.
Usarei um padrão de chave e um modelo de dados normalizado, quando fizer sentido. Ao fazer isso, temos a capacidade de ler e gravar somente os dados exatos de que precisamos, quando precisamos e como precisamos, mas quando precisamos consultar dados com N1QL, também podemos fazer isso. Alguns desses padrões de design podem parecer estranhos para você, mas é assim que você poderá executar e dimensionar facilmente o Couchbase para atingir dezenas ou centenas de milhares de operações por segundo... ou até mais. Em blogs posteriores, falarei sobre como queremos consultar alguns dados para fazer análises ou algo do gênero mais tarde.
Mais uma vez, quero tentar projetar os documentos em torno do aplicativo, obtendo apenas os dados de que precisa, exatamente quando precisa, e lendo-os com a chave e não consultando. Não há necessidade de índices, exibições, junções etc. É assim que você obterá o melhor desempenho e escalabilidade absolutos com o Couchbase.
O documento de informações de login
Separei as informações de login do usuário em um documento próprio por alguns motivos, e esse mesmo tipo de filosofia também será usado em outros documentos mais tarde.
- As informações de login são necessárias com frequência, pois os usuários se autenticam muito em nosso aplicativo e, quando o serviço precisa desses dados, ele não precisa do restante das informações do usuário na maioria das vezes. Sim, o Couchbase tem edição de subdocumentos, mas, como a maioria dos bancos de dados NoSQL, no back-end o documento ainda é remontado e transmitido por completo, por exemplo, replicação entre clusters (XDCR). Prefiro evitar isso sempre que possível.
- Prefiro que o serviço apenas retorne do banco de dados para o aplicativo um documento de 141 bytes do que todos os 1,41k ou mais com o documento principal. A edição de subdocumentos pode atenuar isso, mas não os dois motivos seguintes.
- Para fins de desempenho, prefiro manter uma tonelada de documentos de 141 bytes no cache gerenciado em vez dos maiores quando, novamente, nem sempre preciso do documento completo. Manter o documento inteiro no cache pode não ter muita importância quando tenho 100.000 usuários e estou fazendo apenas 1.000 operações por segundo, mas quando tenho milhões de usuários e preciso fazer 10s, se não 100s, de milhares de operações por segundo e preciso manter o desempenho, isso aumenta. Tanto em termos de desempenho quanto de recursos monetários, ou seja, RAM.
- Isso também significa que, para os visitantes regulares do meu serviço, o documento deve estar sempre no cache gerenciado para que eles obtenham o melhor desempenho.
Também quero atualizar esse documento com a data atual no valor lastlogin e com o IP de onde eles vieram cada vez que o usuário fizer login com sucesso. Isso não é rastreado automaticamente pelo Couchbase, mas preciso disso para fins de análise de negócios e para excluir usuários que não se conectaram por um longo período. Nesse caso, também estou atualizando apenas um documento muito pequeno.
Como não é essencial para as operações diárias de autenticação de usuários, para o requisito de exclusão de usuários que não fazem login no sistema há X anos, usaremos esse assunto em outra postagem do blog.
Há também uma entidade no documento chamada "enabled" (habilitado) que pode ser usada no serviço para verificar se o usuário tem permissão para fazer login ou não.
1 2 3 4 5 6 7 8 9 10 |
chave : login-informações::hernandez94 { "lastlogin": "2016-08-01 15:03:40", "pword": "app-hashed-password", "loc": "IP ou fqdn", "habilitado" : verdadeiro, "doc-type" : "login-info", "nome de usuário" : "hernandez94" } |
Uma parte importante aqui é a chave do documento. Esse tipo de padrão de chave é algo que é consistente em meu aplicativo, como você verá mais adiante. Posso facilmente fazer o aplicativo concatenar isso com o nome de usuário exclusivo. Essa chave é importante porque não precisarei consultar esse documento no Couchbase, pois tenho a chave. Conhecer a chave significa que o SDK do Couchbase já sabe a resposta para a pergunta "Onde está o dado que estou procurando?", ao passo que consultar um banco de dados é fazer essa pergunta ao banco de dados e usar a potência do banco de dados (e tudo o que isso implica) para encontrar a resposta e trazer os dados de volta. Portanto, saber a chave e dizer ao banco de dados para ler/gravar esse objeto, especialmente se ele já estiver no cache gerenciado, será extremamente rápido com o Couchbase. Mesmo que o objeto esteja no disco e não no cache gerenciado, ele será rápido e colocado no cache gerenciado para estar pronto para uso em consultas posteriores. Esse gerenciamento de cache está nos bastidores e não é algo que seu aplicativo precise conhecer.
Eu também estava pensando em dividir a entidade "habilitada" do documento JSON em seu próprio objeto de par chave/valor, já que o Couchbase oferece suporte a isso. Eu estava pensando que poderia haver alguns lugares em que eu precisaria apenas saber se o usuário está habilitado no sistema ou não. Embora seja possível, decidi não fazer isso porque já estava começando a normalizar muito os dados e tenho que parar em algum lugar. Nesse caso, por uma questão de complexidade, fazia sentido deixar as coisas como estão.
Um dos outros aspectos a serem observados nesse novo documento é que adicionei as entidades doc-type e username ao esquema do documento. Você verá essas entidades em todos os outros documentos também. O motivo do tipo de documento é que posso fazer uma indexação secundária nele mais tarde. O nome de usuário é para indexação, mas também porque assim posso fazer JOINs no N1QL entre qualquer um desses documentos e o novo documento principal que você verá no final. Em partes posteriores desta série, você verá mais sobre por que isso é importante e como usá-lo a nosso favor.
Recapitulando, separamos essa parte das informações do documento principal do usuário em um documento menor por alguns bons motivos. Precisamos do documento com frequência, mantemos o documento pequeno para que as leituras/gravações sejam eficientes e, portanto, ele deve ser mantido no cache gerenciado para a maioria dos usuários com os quais nos preocupamos. Além de tudo isso, como podemos obter o objeto por sua chave, não precisamos consultar o banco de dados, portanto, as pesquisas são muito rápidas. Também adicionamos valores ao documento JSON para facilitar a consulta posteriormente.
Documento de perguntas de segurança
Criei o documento de perguntas de segurança, pois, diferentemente do documento de informações de login, que é necessário com muita frequência, esses dados devem ser necessários muito raramente. Nas ocasiões em que o serviço precisa dessas informações, ele não precisa especificamente de nenhuma das demais informações do usuário. Portanto, fazia sentido dividi-las em seu próprio objeto e adicionar uma chave que, mais uma vez, pudesse ser concatenada facilmente pelo aplicativo para obter o documento por chave. Também converti isso de uma matriz para que cada pergunta fosse seu próprio objeto. Por exemplo, question1.question ou question2.answer e, no código do meu aplicativo, posso gerar aleatoriamente um número entre 1 e 3 e, em seguida, usar uma API de subdocumento para obter apenas essa pergunta. Eu também teria a opção de mostrar todas as três perguntas, dependendo de como meu aplicativo funciona. Gosto de ter opções.
1 2 3 4 5 6 7 8 9 |
chave : sec-perguntas::hernandez94 { "question1" : { "pergunta" : "A pergunta de segurança 1 vai para aqui", "resposta" : "A resposta à pergunta de segurança 1 fica aqui" }, "question2" : { "pergunta" : "A pergunta de segurança 2 fica aqui", "resposta" : "A resposta à pergunta de segurança 2 fica aqui" }, "question3" : { "pergunta" : "A pergunta de segurança 3 fica aqui", "resposta" : "A resposta à pergunta de segurança 3 fica aqui" }, "doc-type" : "sec-questions", "nome de usuário" : "hernandez94" } |
Além disso, como o documento não é usado com muita frequência, é possível que ele saia do cache gerenciado e eu não me importo. Ele é usado com tão pouca frequência pelos usuários que, se houver um pequeno impacto no desempenho para ir para o disco, aguente, usuário! Não estou pagando para manter todos esses dados na RAM porque você não consegue se lembrar de algo sobre sua conta de usuário.
Documento de funções de segurança do usuário
Eu queria ter uma lista de funções de segurança para associar a um usuário. Como muitas outras coisas, quando preciso dessas informações, não preciso de outras informações sobre o usuário. Provavelmente, terei outro documento em algum lugar definindo as funções de segurança às quais elas estão associadas.
1 2 3 4 5 6 7 |
chave : usuário-sec-funções::hernandez94 { "sec-roles" : [101, 301, 345], "doc-type" : "user-roles", "nome de usuário" : "hernandez94" } |
Documento de funções de segurança
Terei outro conjunto de documentos que definem as funções de segurança a que eles se referem.
1 2 3 4 5 6 7 |
chave : sec-funções::101 { "name" (nome) : "Administrador", "descr" : "Administradores do serviço", "doc-type" : "sec-role" } |
Essa é uma questão interessante, pois pode me trazer problemas mais tarde. Como esse documento pode ser lido com bastante frequência, posso criar um ponto de acesso dependendo da frequência com que meu aplicativo o utiliza. Vi um cliente que mantinha a configuração do aplicativo no Couchbase em um único documento, mas o lia mais de 10.000 vezes por segundo. Embora um único nó do Couchbase possa lidar com isso facilmente, isso se somava a todo o outro tráfego. Portanto, o único nó do cluster que tinha esse documento estava sobrecarregado. Isso não deve ser um problema aqui, mas apenas algo a ser observado. Provavelmente, mais tarde, farei uma postagem sobre como corrigir esse problema, mas 99 vezes em 100, isso não deve ser um problema. Só vi um hot spot no Couchbase uma única vez e a causa foi realmente um problema de design do aplicativo.
Documentos de e-mail, endereços e telefones
Você pode separar as matrizes de e-mail, telefones e/ou endereços do documento original, dependendo de como seu aplicativo usa os dados. Talvez tenhamos um método getEmail() ou getAddress() que seja exposto como parte desse serviço. O método getMail() receberia como entrada o nome de usuário exclusivo e seria capaz de construir facilmente a chave (email-addr::hernandez94) para o documento. Como a normalização em qualquer banco de dados, você pode ir longe demais. Portanto, tenha cuidado e só faça isso se tiver um motivo sólido para fazê-lo.
1 2 3 4 5 6 7 8 |
chave : telefones::móvel::hernandez94 { "doc-type" : "telefone", "num" : "+12345678900", "tipo" : "móvel", "id" : "hernandez94" } |
Fazer documentos para cada número de telefone que o usuário tem, como abaixo, me daria opções tanto para o acesso KV quanto para o acesso N1QL. A consulta abaixo me forneceria todos os números de telefone desse usuário e seu tipo (por exemplo, celular, trabalho etc.)
1 |
SELECIONAR num, tipo DE perfis de usuário ONDE id = "hernandez94" E doc-tipo = "telefone"; |
Você também poderia concatenar a chave do documento acima e obtê-la por meio do KV. Isso lhe dá opções.
O novo documento principal
Este é o documento principal agora. Se os padrões de usuário do meu aplicativo exigissem isso, eu separaria itens como endereços e telefones, mas, para fins de exemplo, decidi deixá-los, pois todos os dados que deixei aqui são dados de que não preciso com muita frequência ou, quando preciso, é ao mesmo tempo. Eu poderia normalizar mais? Sim, por exemplo, eu poderia dividir a data de criação em um objeto de valor-chave, já que quero registrá-la, mas raramente precisarei dela, mas, por enquanto, isso me leva aonde preciso estar. Não quero ficar muito louco. Além disso, quanto mais documentos você tiver, mais metadados terá também.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
chave : hernandez94 { "firstName" : "Jennifer", "middleName" : "Maria", "lastName" : "Hernandez", "endereços" : [ { "tipo" : "casa", "addr1" : "1929 Crisanto Ave", "endereço" : "Apt 123", "addr3" : "c/o J. Hernandez", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94040" }, { "tipo" : "trabalho", "addr1" : "2700 W El Camino Real", "addr2" : "Suíte #123", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94040" }, { "tipo" : "faturamento", "addr1" : "P.O. Box 123456", "cidade" : "Vista da montanha", "estado" : "CA", "país" : "EUA", "pcode" : "94041" } ], "telefones" : [ { "tipo" : "trabalho", "num" : "+12345678900" }, { "tipo" : "móvel", "num" : "+12345678901" } ], "createdate" : "2016-08-01 15:03:40", "doc-type" : "usuário" } |
Exemplo de código Java
Este é um exemplo de código Java de uma operação de obtenção em massa para obter todos os documentos associados ao usuário:
Isso permite que você obtenha todos os documentos associados a esse usuário de forma muito fácil e rápida. É como colocar diferentes partes de dados em diferentes tabelas em um banco de dados relacional e, em seguida, fazer uma junção para obter todas as informações. Isso seria MUITO mais rápido do que isso.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Aglomerado agrupamento = CouchbaseCluster.criar(); Balde balde = agrupamento.openBucket(); Lista foundDocs = Observável .apenas( ID do usuário, "sec-questions::" + ID do usuário, "login-info::" + ID do usuário, "user-sec-roles::" + ID do usuário) .flatMap(novo Func1<Cordas, Observável>() { @Substituir público Observável chamada(Cordas id) { retorno balde.assíncrono().obter(id); } }) .toList() .toBlocking() .único(); |
Eu poderia pensar em modificar o código para garantir que eu tivesse todos os documentos quando terminasse essa chamada e, se não, fazer uma leitura de réplica para os documentos ausentes, no caso de um nó estar inativo, mas você entendeu a ideia.
Para obter mais informações sobre como fazer obtenções em massa, consulte a respectiva documentação do SDK do Couchbase.
Resumo
O Couchbase oferece uma maneira diferente de modelar seus dados em comparação com outros bancos de dados de documentos e, especialmente, com bancos de dados relacionais. Ao dividir alguns dados em documentos diferentes, mas relacionados por informações na chave e no documento, podemos obter os dados exatos de que precisamos para o aplicativo quando precisarmos. Mantemos exatamente os dados que queremos atualizados no cache gerenciado que é usado com frequência, mas se precisarmos de todos os documentos do usuário, podemos fazer uma operação em massa em todos eles muito rapidamente. A última parte importante é o padrão de chave usado aqui. Novamente, acessar objetos por chave é a diferença entre já saber a resposta e ter de fazer uma pergunta, como em outros bancos de dados.
Toda essa conversa sobre desempenho e padrões-chave ignora os momentos em que queremos de fato consultar os dados. Quando você tem perguntas como "Quantos usuários têm um código postal de endereço residencial 98038?". Mas, como eu disse antes, isso será deixado para outra postagem do blog nesta série.
Muito bem escrito, Kirk...., estou aguardando ansiosamente a parte II dessa série.
Olá Kirk, ótimo artigo. Estou começando a trabalhar com NoSQL e quero começar a usar o Couchbase, e esse é um ótimo material de aprendizado.
Gosto de como você usa as chaves de cadeia de caracteres essencialmente como uniões entre documentos. Estou discutindo o que fazer em meu cenário mais complexo: Digamos que eu esteja criando um aplicativo que permita aos usuários armazenar dados adicionais relacionados a tweets do Twitter, por exemplo, "salvar este tweet como favorito". Um único usuário poderia facilmente ter milhares desses favoritos acumulados ao longo do tempo. Essencialmente, essa é uma relação de muitos para muitos entre Usuários e Tweets. Seguindo seu exemplo, a chave para esses pequenos documentos poderia ser: _
No meu cenário, todos esses relacionamentos são estritamente privados para o usuário que os criou. E todos eles precisam ser replicados no dispositivo de um usuário por meio do Couchbase Lite. Por esses motivos, seria melhor armazenar todos eles em um único documento para esse usuário ou, talvez, em documentos fragmentados com base no tempo, no fluxo do Twitter etc.?
Obrigado!
Essa é uma pergunta difícil, pois há prós e contras em ambos os casos. Se você armazenar todos eles em um único documento, em que ponto o usuário ultrapassaria o limite de 20 MB do documento ou teria que arrastar um grande documento JSON apenas para adicionar um tweet a ele? Por outro lado, se cada tweet estiver em seu próprio documento, você poderá chegar a uma situação em que terá bilhões de objetos e armazenará muitos metadados, pois o Couchbase armazena aproximadamente 54 bytes por objeto de dados. Você pode ejetar isso também, mas terá um impacto no desempenho para verificar se um documento existe.
De qualquer forma, eu recomendaria analisar três possibilidades.
1) Ver se o armazenamento de cada tweet como um objeto, mas a chave seria algo que descrevi em minha outra postagem no blog sobre modelagem de objetos, funcionaria. http://bit.ly/1Hx3a74
2) Outra opção que já vi ser usada com grande efeito é ter cada tweet em um documento separado, mas depois ter um documento de índice manual por usuário. Então, para obter os favoritos desse usuário, você pega o documento que tem o \"index\" dele e nesse documento está a lista dos IDs de objeto dos tweets que são seus favoritos. Se você precisar obter todos eles, agora que tem a lista de objetos a serem obtidos, use as operações em massa do SDK do Couchbase e obtenha todos ou a parte de que precisa. Isso faz sentido?
3) Uma combinação de 1 e 2, dependendo de seu caso de uso e do perfil de desempenho necessário.
Ótimo artigo. Obrigado pelas informações. Alguém sabe onde posso encontrar um formulário em branco de \"como enviar um aplicativo por e-mail\" para preencher?
Oi jeannie, eu
Consegui \"enviar um e-mail para o aplicativo\" a partir deste link
http://goo.gl/yoGwr2. Ele também me permitiu fazer download, editar, imprimir, salvar, assinar, enviar por e-mail ou até mesmo por fax.
Como enviar um e-mail para quem?
Belo artigo, obrigado! Estou aguardando a segunda parte.
Bom artigo.
A modelagem de dados do User Profile Store só considera o uso do Couchbase Server. Se houver um conselho sobre a modelagem de dados quando eu usar o Couchbase Server e o Couchbase Mobile, será útil.
Por exemplo, ao usar o Couchbase Mobile, devemos considerar a restrição de roteamento/ACL do SG, a restrição de consulta do CouchbaseLite por mapa/redução etc.
O Couchbase Mobile não é minha área de especialização e, portanto, duvido que eu faça justiça ao tópico. No entanto, vou repassar o assunto para aqueles que possam ajudar e escrever algo para você. A outra opção para você, se ainda não o fez, é usar os fóruns do Couchbase para perguntar sobre isso.
Você também pode começar aqui, e estaremos lançando mais treinamentos sobre o Couchbase Mobile nas próximas semanas. http://developer.couchbase.com…
Ótimo artigo, Kirk. Informações muito detalhadas. Há alguma data em mente para a parte 2 deste artigo?
Obrigado!
[...] exemplos de como você pode usar um padrão de ID de objeto padronizado em seu aplicativo, consulte esta e esta postagem de blog que escrevi. Mesmo que os casos de uso específicos nos blogs não sejam aplicáveis a [...]
Como ele resolveu esse problema, obrigado por compartilhar, continue assim.
Fornecedores de embalagens e impressão