View a markdown version of this page

Práticas recomendadas para gerenciar relações de muitos para muitos no DynamoDB - Amazon DynamoDB

Práticas recomendadas para gerenciar relações de muitos para muitos no DynamoDB

As listas de adjacências são um padrão de design útil para modelar as relações muitos para muitos no Amazon DynamoDB. De modo mais geral, elas oferecem uma forma de representar os dados gráfico (nós e bordas) no DynamoDB.

Padrão de design da lista de adjacências

Quando entidades diferentes de um aplicativo têm uma relação muitos para muitos entre elas, a relação pode ser modelada como uma lista de adjacências. Nesse padrão, todas as entidades de nível superior (sinônimos para nós no modelo de gráfico) são representadas usando a chave de partição. Qualquer relação com outras entidades (bordas em um gráfico) é representada como um item na partição configurando o valor da chave de classificação como o ID da entidade de destino (nó de destino).

As vantagens desse padrão incluem a duplicação mínima de dados e padrões simplificados de consulta para encontrar todas as entidades (nós) relacionadas a uma entidade de destino (o ponto em um nó de destino).

Como exemplo real, esse padrão foi útil em um sistema de faturamento em que as faturas continham várias contas. Uma conta pode pertencer a várias faturas. A chave de partição nesse exemplo é um InvoiceID ou um BillID. As partições BillID têm todos os atributos específicos para as contas. As partições InvoiceID têm um item que armazena os atributos específicos à fatura e um item para cada BillID implementado para a fatura.

O esquema é semelhante ao seguinte.

Exemplo de esquema da tabela para lista de adjacências de faturamento.

Usando o esquema anterior, você pode ver que todas as contas para uma fatura podem ser consultadas usando a chave primária na tabela. Para pesquisar todas as faturas que contêm uma parte de uma conta, crie um índice secundário global na chave de classificação da tabela.

As projeções do índice secundário global são semelhantes ao seguinte.

Exemplo de projeção de GSI para lista de adjacências de faturamento.

Padrão de gráficos materializados

Muitos aplicativos precisam entender classificações entre pares, relações entre entidades e o estado da entidade vizinha. Caso seu aplicativo use esses tipos de fluxos de trabalho em estilo gráfico, considere o seguinte padrão de design de esquema.

Como exemplo concreto, considere um aplicativo de rede social. Nesse aplicativo, as pessoas se relacionam com outras pessoas, possuem habilidades, moram em lugares e têm datas associadas (como datas de nascimento). Cada pessoa é um no gráfico. As conexões entre pessoas, como amizades, são bordas. As associações entre pessoas e atributos (habilidades, lugares, datas) também são bordas.

Com o padrão de gráfico materializado, você pode armazenar nós e bordas em uma única tabela do DynamoDB e percorrer relacionamentos com eficiência. Os diagramas a seguir mostram como modelar esse gráfico de rede social. O primeiro diagrama mostra a estrutura da tabela primária. Os diagramas subsequentes mostram as projeções do índice secundário global.

Esquema de tabela primária para o padrão de gráfico materializado no DynamoDB, mostrando pessoas como chaves de partição com as bordas como itens dentro de cada partição.
Primeira projeção de índice secundário global no DynamoDB, baseada no atributo de dados sobrecarregado para consultas por datas, nomes, lugares e habilidades.
Segunda projeção de índice secundário global no DynamoDB, baseada na chave composta TypeTarget para pesquisas reversas.

A tabela usa a seguinte estrutura de chave:

  • Chave de partição: o ID da entidade (por exemplo, Person-1, Person-2). Cada partição contém um item de nó e vários itens de borda.

  • Chave de classificação: para itens do nó, o próprio ID da entidade. Para itens de borda, uma composição do tipo de borda e do destino (por exemplo, Friend-Person-2 ou Skill-DynamoDB).

Os itens da borda contêm um atributo Target e um Type. Eles formam a chave composta "TypeTarget" que identifica itens na tabela primária e no segundo índice secundário global. Por exemplo, "a Pessoa-1 é amiga da Pessoa-2" produz Type=Friend, Target=Person-2 e TypeTarget=Friend-Person-2.

O primeiro índice secundário global é criado no atributo Data. Esse atributo usa a sobrecarga de índice secundário global para indexar vários tipos de atributos dentro do mesmo índice:

  • Dates: datas de nascimento, datas de adesão (por exemplo, 1971-12-21)

  • Names: nomes de exibição (por exemplo, Ana Carolina Silva)

  • Places: localizações (por exemplo, Seattle)

  • Skills: competências (por exemplo, DynamoDB)

Você pode usar esse único índice secundário global para consultar todas as pessoas nascidas em uma data específica, todas as pessoas em um local ou todas as pessoas com uma habilidade específica.

O segundo índice secundário global usa TypeTarget como chave de partição para pesquisas reversas. Por exemplo, você pode encontrar todas as pessoas que listam Person-2 como amiga consultando TypeTarget=Friend-Person-2.

À medida que você inserir itens na tabela, poderá usar uma estratégia de fragmentação inteligente para distribuir os conjuntos de item com grandes agregações (data de nascimento, habilidade) nas partições lógicas nos índices secundários globais que forem necessárias para evitar problemas de leitura/gravação dinâmicas.

Com essa combinação de padrões de design, você obtém um datastore sólido para fluxos de trabalho de gráfico altamente eficientes e em tempo real. Você pode usá-lo para criar consultas de alto desempenho de estado de entidade vizinha e agregação de borda para mecanismos de recomendação, aplicativos de rede social, classificações de nós, agregações de subárvore e outros casos de uso comuns de gráficos.

Se seu caso de uso não for sensível a consistência de dados em tempo real, você poderá usar um processo do Amazon EMR programado para preencher as bordas com agregações relevantes de resumo de gráfico para seus fluxos de trabalho de um modo econômico. Se o aplicativo não precisar saber imediatamente quando uma borda é adicionada ao gráfico, será possível usar um processo programado para agregar resultados.

Para manter algum nível de consistência, o design poderia incluir Amazon DynamoDB Streams e AWS Lambdaparar processar atualizações da borda. Ele também poderia usar um trabalho do Amazon EMR para validar os resultados em um intervalo regular. Essa abordagem é ilustrada pelo diagrama a seguir. Ela é usada comumente em aplicativos de rede social, onde o custo de uma consulta em tempo real é alto, e a necessidade de saber imediatamente as atualizações de usuário individual é baixa.

Diagrama ilustrando o fluxo de trabalho do gráfico.

Os aplicativos de segurança e gerenciamento de serviços de TI (ITSM - IT service-management) geralmente precisa responder em tempo real às alterações de estado da entidade compostas de agregações complexas de borda. Esses aplicativos precisam de um sistema que seja compatível com várias agregações de nó em tempo real de relações de segundo e terceiros níveis ou de percursos complexos de borda. Se o seu caso de uso exigir esses tipos de fluxos de trabalho de consulta de gráficos em tempo real, recomendamos que você considere o uso do Amazon Neptune para gerenciar esses fluxos de trabalho.

nota

Se você precisar consultar conjuntos de dados altamente conectados ou percorrer vários nós (consultas multi-hop) com latência de milissegundos, considere a possibilidade de usar o Amazon Neptune. O Amazon Neptune é um mecanismo de banco de dados de grafos de alto desempenho e com projeto específico. Ele é otimizado para armazenar bilhões de relacionamentos e consultar grafos com latência de milissegundos.