A modelagem de dados JSON é uma parte essencial do uso de um banco de dados de documentos como o Couchbase. Além de entender os conceitos básicos de JSON, há duas abordagens principais para modelar relacionamentos entre dados que serão abordados nesta postagem do blog.

Os exemplos nesta postagem serão baseados no exemplo de faturas que mostrei em Ferramenta CSV para migrar do Relacional para o Couchbase.

Atualização de dados importados

No exemplo anterior, comecei com duas tabelas de um banco de dados relacional: Invoices (faturas) e InvoicesItems (itens de faturas). Cada item de fatura pertence a uma fatura, o que é feito com uma chave estrangeira em um banco de dados relacional.

Fiz uma importação muito simples (ingênua) desses dados para o Couchbase. Cada linha se tornou um documento em um bucket de "preparação".

Data imported from CSV

Em seguida, precisamos decidir se esse design de modelagem de dados JSON é adequado ou não (acho que não é, como se o balde chamado "staging" já não tivesse revelado isso).

Duas abordagens para a modelagem de dados JSON de relacionamentos

Com um banco de dados relacional, há apenas uma abordagem: normalizar seus dados. Isso significa tabelas separadas com chaves estrangeiras que vinculam os dados entre si.

Com um banco de dados de documentos, há duas abordagens. Você pode manter os dados normalizados ou pode desnormalizá-los aninhando-os em seu documento pai.

Normalizado (documentos separados)

Um exemplo do estado final do normalizado representa uma única fatura distribuída em vários documentos:

Isso está alinhado com a importação direta de CSV. O InvoiceId em cada documento de item de fatura é semelhante O Couchbase é um banco de dados de documentos distribuído, mas observe que o Couchbase (e os bancos de dados de documentos distribuídos em geral) não impõe esse relacionamento da mesma forma que os bancos de dados relacionais. Essa é uma troca feita para satisfazer as necessidades de flexibilidade, escalabilidade e desempenho de um sistema distribuído.

Observe que, neste exemplo, os documentos "filhos" apontam para o pai por meio de InvoiceId. Mas também poderia ser o contrário: o documento "pai" poderia conter uma matriz das chaves de cada documento "filho".

Desnormalizado (aninhado)

O estado final do aninhado A abordagem de um documento único para representar uma fatura.

Observe que o "InvoiceId" não está mais presente nos objetos da tabela Itens array. Esses dados não são mais estrangeiros - agora são nacionais -, portanto, esse campo não é mais necessário.

Regras básicas de modelagem de dados JSON

Você já deve estar pensando que o segundo é uma opção natural nesse caso. Uma fatura nesse sistema é uma opção natural raiz agregada. No entanto, nem sempre é simples e óbvio quando e como escolher entre essas duas abordagens em seu aplicativo.

Aqui estão algumas regras de ouro para saber quando escolher cada modelo:

Tabela 1. Folha de consulta de dados de modelagem
Se ... Então, considere...

O relacionamento é de 1 para 1 ou de 1 para muitos

Objetos aninhados

O relacionamento é de muitos para 1 ou de muitos para muitos

Documentos separados

As leituras de dados são, em sua maioria, campos pai

Documento separado

As leituras de dados são, em sua maioria, campos pai + filho

Objetos aninhados

As leituras de dados são, em sua maioria, parentais ou filho (não ambos)

Documentos separados

As gravações de dados são, em sua maioria, pai e criança (ambos)

Objetos aninhados

Exemplo de modelagem

Para explorar isso mais a fundo, vamos fazer algumas suposições sobre o sistema de faturas que estamos criando.

  • Um usuário geralmente visualiza a fatura inteira (incluindo os itens da fatura)
  • Quando um usuário cria uma fatura (ou faz alterações), ele atualiza os campos "raiz" e os "itens" juntos
  • Existem alguns consultas (mas não muitas) no sistema que se preocupam apenas com os dados raiz da fatura e ignoram os campos "itens"

Então, com base nesse conhecimento, sabemos que:

  1. A relação é de 1 para muitos (uma única fatura tem muitos itens)
  2. As leituras de dados são principalmente campos pai + filho juntos

Portanto, "objetos aninhados" parece ser o design correto.

Lembre-se de que essas não são regras rígidas e rápidas que sempre serão aplicadas. Elas são apenas diretrizes para ajudá-lo a começar. A única "prática recomendada" é usar seu próprio conhecimento e experiência.

Transformação de dados de preparação com N1QL

Agora que fizemos alguns exercícios de modelagem de dados JSON, é hora de transformar os dados no bucket de teste de documentos separados que vieram diretamente do banco de dados relacional para o design de objetos aninhados.

Há muitas abordagens para isso, mas vou mantê-las bem simples e usar o poderoso recurso do Couchbase Linguagem N1QL para executar consultas SQL em dados JSON.

Preparando os dados

Primeiro, crie um bucket de "operação". Vou transformar os dados e movê-los para o bucket "staging" (que contém os dados diretos da operação). Importação de CSV) para o compartimento "operação".

Em seguida, vou marcar os documentos "raiz" com um campo "tipo". Essa é uma maneira de marcar os documentos como sendo de um determinado tipo e será útil mais tarde.

Sei que os documentos raiz têm um campo chamado "InvoiceNum" e que os itens não têm esse campo. Portanto, essa é uma maneira segura de diferenciar.

Em seguida, preciso modificar os itens. Anteriormente, eles tinham uma chave estrangeira que era apenas um número. Agora, esses valores devem ser atualizados para apontar para a nova chave do documento.

Isso é apenas acrescentar "invoice::" ao valor. Observe que os documentos raiz não têm um campo InvoiceId, portanto, eles não serão afetados por essa consulta.

Depois disso, preciso criar um índice nesse campo.

Preparação de um índice

Esse índice será necessário para a união transformacional que virá a seguir.

Agora, antes de tornar esses dados operacionais, vamos executar um SELECIONAR para obter uma visualização e garantir que os dados serão unidos da forma esperada. Use a função NEST operação:

O resultado dessa consulta deve ser um total de três documentos de fatura raiz.

Results of transformation with N1QL

Os itens da fatura agora devem ser aninhados em uma matriz "Items" dentro da fatura principal (eu os coloquei em colapso na captura de tela acima por uma questão de brevidade).

Mover os dados para fora da preparação

Depois de verificar se isso está correto, os dados podem ser movidos para o bucket de "operação" usando um INSERIR que será apenas uma pequena variação do comando acima SELECIONAR comando.

Se você é novo no N1QL, há algumas coisas que devem ser destacadas aqui:

  • INSERIR sempre usará CHAVE e VALOR. Você não lista todos os campos nessa cláusula, como faria em um banco de dados relacional.
  • META(i).id é uma forma de acessar a chave de um documento
  • A sintaxe literal do JSON sendo SELECIONADO COMO v é uma forma de especificar quais campos você deseja mover. Os curingas podem ser usados aqui.
  • NEST é um tipo de união que aninhará os dados em uma matriz em vez de no nível da raiz.
  • PARA i especifica o lado esquerdo do NA CHAVE join. Essa sintaxe é provavelmente a parte mais fora do padrão do N1QL, mas a próxima versão principal do Couchbase Server incluirá a funcionalidade "ANSI JOIN", que será muito mais natural para leitura e gravação.

Depois de executar essa consulta, você deverá ter um total de 3 documentos no seu bucket de "operação", representando 3 faturas.

Result from JSON data modeling transformation

Você pode excluir/descarregar o bucket de teste, pois ele agora contém dados obsoletos. Ou você pode mantê-lo por perto para fazer mais experimentos.

Resumo

Migrar dados diretamente para o Couchbase Server pode ser tão fácil quanto importar via CSV e transformar com algumas linhas de N1QL. A modelagem real e a tomada de decisões exigem mais tempo e reflexão. Depois de decidir como modelar, o N1QL oferece a flexibilidade de transformar dados relacionais planos e dispersos em um modelo de documento orientado a agregados.

Mais recursos:

Sinta-se à vontade para entrar em contato comigo se tiver alguma dúvida ou precisar de ajuda. Eu sou
@mgroves no Twitter. Você também pode fazer perguntas no Fóruns do Couchbase. Há especialistas em N1QL lá que são muito receptivos e podem ajudá-lo a escrever o N1QL para acomodar sua modelagem de dados JSON.

Autor

Postado por Matthew Groves

Matthew D. Groves é um cara que adora programar. Não importa se é C#, jQuery ou PHP: ele enviará solicitações de pull para qualquer coisa. Ele tem programado profissionalmente desde que escreveu um aplicativo de ponto de venda QuickBASIC para a pizzaria de seus pais nos anos 90. Atualmente, ele trabalha como gerente sênior de marketing de produtos da Couchbase. Seu tempo livre é passado com a família, assistindo aos Reds e participando da comunidade de desenvolvedores. Ele é autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP.

Deixar uma resposta