Usar o DynamoDB como armazenamento de dados para uma loja virtual - Amazon DynamoDB

Usar o DynamoDB como armazenamento de dados para uma loja virtual

Esse caso de uso trata do uso do DynamoDB como armazenamento de dados para uma loja on-line (ou loja eletrônica).

Caso de uso

Uma loja on-line permite que os usuários naveguem por diferentes produtos e, em algum momento, os comprem. Com base na fatura gerada, o cliente pode pagar usando um código de desconto ou vale-presente e depois pagar o valor restante com um cartão de crédito. Os produtos adquiridos serão retirados de um dos vários armazéns e enviados ao endereço fornecido. Os padrões de acesso típicos para uma loja on-line incluem:

  • Obter cliente para determinado customerId

  • Obter produto para determinado productId

  • Obter armazém para determinado warehouseId

  • Obter um inventário de produtos para todos os armazéns por meio de um productId

  • Obter pedido para determinado orderId

  • Obter todos os produtos de determinado orderId

  • Obter fatura para determinado orderId

  • Obter todos os envios para determinado orderId

  • Obter todos os pedidos de determinado productId em determinado intervalo de datas

  • Obter fatura para determinado invoiceId

  • Obter todos os pagamentos para determinado invoiceId

  • Obter detalhes de envio para determinado shipmentId

  • Obter todos os envios para determinado warehouseId

  • Obter o inventário de todos os produtos para determinado warehouseId

  • Obter todas as faturas para determinado customerId em um intervalo de datas específico

  • Obter todos os produtos encomendados por determinado customerId em um intervalo de datas específico

Diagrama de relacionamento de entidades

Este é o diagrama de relacionamento de entidades (ERD) que usaremos para modelar o DynamoDB como um armazenamento de dados de uma loja on-line.

ERD para o modelo de dados de uma loja on-line com entidades, como Product, Order, Payment e Customer.

Padrões de acesso

Este é o padrão de acesso que consideraremos ao usar o DynamoDB como um armazenamento de dados de uma loja on-line.

  1. getCustomerByCustomerId

  2. getProductByProductId

  3. getWarehouseByWarehouseId

  4. getProductInventoryByProductId

  5. getOrderDetailsByOrderId

  6. getProductByOrderId

  7. getInvoiceByOrderId

  8. getShipmentByOrderId

  9. getOrderByProductIdForDateRange

  10. getInvoiceByInvoiceId

  11. getPaymentByInvoiceId

  12. getShipmentDetailsByShipmentId

  13. getShipmentByWarehouseId

  14. getProductInventoryByWarehouseId

  15. getInvoiceByCustomerIdForDateRange

  16. getProductsByCustomerIdForDateRange

Evolução do design do esquema

Usando NoSQL Workbench para DynamoDB, importe AnOnlineShop_1.json para criar um modelo de dados chamado AnOnlineShop e uma tabela chamada OnlineShop. Observe que usamos os nomes genéricos PK e SK para a chave de partição e a chave de classificação. Essa é uma prática usada para armazenar diferentes tipos de entidade na mesma tabela.

Etapa 1: abordar o padrão de acesso 1 (getCustomerByCustomerId)

Importe AnOnlineShop_2.json para lidar com o padrão de acesso 1 (getCustomerByCustomerId). Algumas entidades não têm relacionamentos com outras, então usaremos o mesmo valor de PK e SK para elas. Nos dados de exemplo, observe que as chaves usam um prefixo c# a fim de distinguir o customerId de outras entidades que serão adicionadas posteriormente. Essa prática também é repetida para outras entidades.

Para abordar esse padrão de acesso, pode ser usada uma operação GetItem com PK=customerId e SK=customerId.

Etapa 2: abordar o padrão de acesso 2 (getProductByProductId)

Importe AnOnlineShop_3.json para abordar o padrão de acesso 2 (getProductByProductId) para a entidade product. As entidades do produto têm p# como prefixo e o mesmo atributo de chave de classificação foi usado para armazenar customerID, bem como productID. A nomenclatura genérica e o particionamento vertical nos permite criar essas coleções de itens para um design de tabela única eficaz.

Para abordar esse padrão de acesso, pode ser usada uma operação GetItem com PK=productId e SK=productId.

Etapa 3: abordar o padrão de acesso 3 (getWarehouseByWarehouseId)

Importe AnOnlineShop_4.json para abordar o padrão de acesso 3 (getWarehouseByWarehouseId) para a entidade warehouse. No momento, temos as entidades customer, product e warehouse adicionadas à mesma tabela. Elas são diferenciadas usando prefixos e o atributo EntityType. Um atributo de tipo (ou nomenclatura de prefixo) melhora a legibilidade do modelo. A legibilidade seria afetada se simplesmente armazenássemos IDs alfanuméricos para entidades diferentes no mesmo atributo. Seria difícil diferenciar uma entidade da outra na ausência desses identificadores.

Para abordar esse padrão de acesso, pode ser usada uma operação GetItem com PK=warehouseId e SK=warehouseId.

Tabela base:

Design de tabela do DynamoDB com prefixos e entityType para receber dados do warehouse por meio do ID.

Etapa 4: abordar o padrão de acesso 4 (getProductInventoryByProductId)

Importe AnOnlineShop_5.json para abordar o padrão de acesso 4 (getProductInventoryByProductId). A entidade warehouseItem é usada para acompanhar o número de produtos em cada armazém. Esse item normalmente é atualizado quando um produto é adicionado ou removido de um depósito. Conforme visto no ERD, há uma relação de muitos para muitos entre product e warehouse. Aqui, a relação de um para muitos de product para warehouse é modelada como warehouseItem. Posteriormente, a relação de um para muitos de warehouse para product também será modelada.

O padrão de acesso 4 pode ser abordado com uma consulta em PK=ProductId e SK begins_with “w#“.

Para obter mais informações sobre begins_with() e outras expressões que podem ser aplicadas para chaves de classificação, consulte Expressões de condição de chave.

Tabela base:

Design de tabela para consultar ProductID e warehouseId para rastrear o estoque de produtos em determinado depósito.

Etapa 5: abordar os padrões de acesso 5 (getOrderDetailsByOrderId) e 6 (getProductByOrderId)

Adicione um mais alguns itens customer, product e warehouse à tabela importando AnOnlineShop_6.json. Depois, importe AnOnlineShop_7.json para criar uma coleção de itens para order que possa abordar os padrões de acesso 5 (getOrderDetailsByOrderId) e 6 (getProductByOrderId). Você pode ver a relação de um para muitos entre order e product modelada como entidades orderItem.

Para abordar o padrão de acesso 5 (getOrderDetailsByOrderId), consulte a tabela com PK=orderId. Isso fornecerá todas as informações sobre o pedido, incluindo customerId e produtos encomendados.

Tabela base:

Design de tabela para consulta usando orderId para receber informações sobre todos os produtos pedidos.

Para abordar o padrão de acesso 6 (getProductByOrderId), precisamos ler os produtos somente em um order. Consulte a tabela com PK=orderId e SK begins_with “p#” para fazer isso.

Tabela base:

Design de tabela para consulta usando orderId e productId para receber produtos em um pedido.

Etapa 6: abordar o padrão de acesso 7 (getInvoiceByOrderId)

Importe AnOnlineShop_8.json para adicionar uma entidade invoice à coleção de itens de pedido e lidar com o padrão de acesso 7 (getInvoiceByOrderId). Para abordar esse padrão de acesso, é possível usar uma operação de consulta com PK=orderId e SK begins_with “i#”.

Tabela base:

Design de tabela com entidade de fatura na coleção de itens do pedido para receber uma fatura por orderId.

Etapa 7: abordar o padrão de acesso 8 (getShipmentByOrderId)

Importe AnOnlineShop_9.json para adicionar entidades shipment à coleção de itens de pedido e abordar o padrão de acesso 8 (getShipmentByOrderId). Estamos estendendo o mesmo modelo particionado verticalmente por meio da adição de mais tipos de entidade no design de tabela única. Observe como a coleção de itens de pedido contém os diferentes relacionamentos que um entidade order tem com as entidades shipment, orderItem e invoice.

Para receber envios por orderId, você pode realizar uma operação de consulta com PK=orderId e SK begins_with “sh#”.

Tabela base:

Design de tabela com entidade de remessa adicionada à coleção de itens do pedido para receber remessas por ID do pedido.

Etapa 8: abordar o padrão de acesso 9 (getOrderByProductIdForDateRange)

Criamos uma coleção de itens de pedido na etapa anterior. Esse padrão de acesso tem novas dimensões de pesquisa (ProductID e Date), que exige que você escaneie toda a tabela e filtre os registros relevantes para buscar os itens específicos. Para abordar esse padrão de acesso, precisaremos criar um índice secundário global (GSI). Importe AnOnlineShop_10.json para criar uma coleção de itens usando o GSI que possibilita a recuperação de dados de orderItem de várias coleções de itens de pedido. Os dados agora têm GSI1-PK e GSI1-SK, que serão a chave de partição e a chave de classificação de GSI1, respectivamente.

O DynamoDB preenche automaticamente itens que contêm os principais atributos de um GSI da tabela para o GSI. Não há necessidade de fazer manualmente nenhuma inserção adicional no GSI.

Para abordar o padrão de acesso 9, execute uma consulta em GSI1 com GSI1-PK=productId e GSI1SK between (date1, date2).

Tabela base:

Design de tabela com um GSI para receber dados de pedidos de várias coleções de itens de pedidos.

GSI1:

Design de GSI com ProductID e Date como partição e chaves de classificação para receber pedidos por ID do produto e data.

Etapa 9: abordar os padrões de acesso 10 (getInvoiceByInvoiceId) e 11 (getPaymentByInvoiceId)

Importe AnOnlineShop_11.json para abordar os padrões de acesso 10 (getInvoiceByInvoiceId) e 11 (getPaymentByInvoiceId), ambos relacionados a invoice. Embora esses sejam dois padrões de acesso diferentes, eles são realizados usando a mesma condição de chave. Payments são definidos como um atributo com o tipo de dados do mapa na entidade invoice.

nota

GSI1-PK e GSI1-SK estão sobrecarregados para armazenar informações sobre entidades diferentes para que vários padrões de acesso possam ser atendidos por meio do mesmo GSI. Para obter mais informações quanto à sobrecarga do GSI, consulte Sobrecarga de índices secundários globais no DynamoDB.

Para abordar os padrões de acesso 10 e 11, consulte GSI1 com GSI1-PK=invoiceId e GSI1-SK=invoiceId.

GSI1:

Design de GSI com invoiceId como partição e chave de classificação para receber a fatura e o pagamento por ID da fatura.

Etapa 10: abordar os padrões de acesso 12 (getShipmentDetailsByShipmentId) e 13 (getShipmentByWarehouseId)

Importe AnOnlineShop_12.json para abordar os padrões de acesso 12 (getShipmentDetailsByShipmentId) e 13 (getShipmentByWarehouseId).

Observe que as entidades shipmentItem são adicionadas à coleção de itens de pedido na tabela base para poder recuperar todos os detalhes sobre um pedido em uma única operação de consulta.

Tabela base:

Design de tabela com a entidade shipmentItem na coleção de itens do pedido para receber todos os detalhes do pedido.

As chaves de partição e de classificação do GSI1 já foram usadas para modelar uma relação de um para muitos entre shipment e shipmentItem. Para abordar o padrão de acesso 12 (getShipmentDetailsByShipmentId), consulte GSI1 com GSI1-PK=shipmentId e GSI1-SK=shipmentId.

GSI1:

Design de GSI1 com shipmentId como partição e chave de classificação para receber detalhes da remessa por ID da remessa.

Precisaremos criar outro GSI (GSI2) para modelar a nova relação de um para muitos entre warehouse e shipment para o padrão de acesso 13 (getShipmentByWarehouseId). Para abordar esse padrão de acesso, consulte GSI2 com GSI2-PK=warehouseId e GSI2-SK begins_with “sh#”.

GSI2:

Design de GSI2 com warehouseId e shipmentId como partição e chaves de classificação para receber remessas por armazém.

Etapa 11: abordar os padrões de acesso 14 (getProductInventoryByWarehouseId), 15 (getInvoiceByCustomerIdForDateRange) e 16 (getProductsByCustomerIdForDateRange)

Importe AnOnlineShop_13.json para adicionar dados relacionados ao próximo conjunto de padrões de acesso. Para abordar o padrão de acesso 14 (getProductInventoryByWarehouseId), consulte GSI2 com GSI2-PK=warehouseId e GSI2-SK begins_with “p#”.

GSI2:

Design de GSI2 com warehouseId e productId como partição e chaves de classificação para abordar o padrão de acesso 14.

Para abordar o padrão de acesso 15 (getInvoiceByCustomerIdForDateRange), consulte GSI2 com GSI2-PK=customerId e GSI2-SK between (i#date1, i#date2).

GSI2:

Design de GSI2 com customerId e intervalo de datas da fatura como partição e chaves de classificação para abordar o padrão de acesso 15.

Para abordar o padrão de acesso 16 (getProductsByCustomerIdForDateRange), consulte GSI2 com GSI2-PK=customerId e GSI2-SK between (p#date1, p#date2).

GSI2:

Design de GSI2 com customerId e intervalo de datas do produto como partição e chaves de classificação para abordar o padrão de acesso 16.
nota

No NoSQL Workbench, as facetas representam os diferentes padrões de acesso a dados de uma aplicação para o DynamoDB. As facetas oferecem uma maneira de visualizar um subconjunto dos dados em uma tabela, sem precisar ver os registros que não atendam às restrições da faceta. As facetas são consideradas uma ferramenta visual de modelagem de dados e não existem como uma estrutura utilizável no DynamoDB, pois são puramente um apoio para a modelagem de padrões de acesso.

Importe AnOnlineShop_facets.json para ver as facetas desse caso de uso.

Todos os padrões de acesso e a forma como o design do esquema os aborda estão resumidos na tabela abaixo:

Padrão de acesso Tabela base/GSI/LSI Operation Valor da chave de partição Valores de chave de classificação
getCustomerByCustomerId Tabela base GetItem PK=customerId SK=customerId
getProductByProductId Tabela base GetItem PK=productId SK=productId
getWarehouseByWarehouseId Tabela base GetItem PK=warehouseId SK=warehouseId
getProductInventoryByProductId Tabela base Consulta PK=productId SK begins_with "w#"
getOrderDetailsByOrderId Tabela base Consulta PK=orderId
getProductByOrderId Tabela base Consulta PK=orderId SK begins_with "p#"
getInvoiceByOrderId Tabela base Consulta PK=orderId SK begins_with "i#"
getShipmentByOrderId Tabela base Consulta PK=orderId SK begins_with "sh#"
getOrderByProductIdForDateRange GSI1 Consulta PK=productId SK entre date1 e date2
getInvoiceByInvoiceId GSI1 Consulta PK=invoiceId SK=invoiceId
getPaymentByInvoiceId GSI1 Consulta PK=invoiceId SK=invoiceId
getShipmentDetailsByShipmentId GSI1 Consulta PK=shipmentId SK=shipmentId
getShipmentByWarehouseId GSI2 Consulta PK=warehouseId SK begins_with "sh#"
getProductInventoryByWarehouseId GSI2 Consulta PK=warehouseId SK begins_with "p#"
getInvoiceByCustomerIdForDateRange GSI2 Consulta PK=customerId SK entre i#date1 and i#date2
getProductsByCustomerIdForDateRange GSI2 Consulta PK=customerId SK entre p#date1 and p#date2

Esquema final da loja on-line

Veja aqui os designs do esquema final. Para baixar esse design de esquema como arquivo JSON, consulte Padrões de design do DynamoDB no GitHub.

Tabela base

Esquema final da tabela base para uma loja on-line com atributos, como EntityName e Name.

GSI1

Esquema de GSI1 final para a tabela base de uma loja on-line com atributos, como EntityType.

GSI2

Esquema de GSI2 final para a tabela base de uma loja on-line com atributos, como EntityType.

Como usar o NoSQL Workbench com esse design de esquema

Você pode importar esse esquema final para o NoSQL Workbench, uma ferramenta visual que fornece atributos de modelagem de dados, visualização de dados e desenvolvimento de consultas para o DynamoDB, se quiser explorar e editar ainda mais seu novo projeto. Para começar, siga estas etapas:

  1. Baixe o NoSQL Workbench. Para ter mais informações, consulte Baixar o NoSQL Workbench para DynamoDB.

  2. Baixe o arquivo do esquema JSON listado acima, que já está no formato do modelo NoSQL Workbench.

  3. Importe o arquivo do esquema JSON para o NoSQL Workbench. Para ter mais informações, consulte Importar um modelo de dados existente.

  4. Depois de importar para o NOSQL Workbench, você pode editar o modelo de dados. Para ter mais informações, consulte Editar um modelo de dados existente.

  5. Para visualizar o modelo de dados, adicionar dados de exemplo ou importar dados de exemplo de um arquivo CSV, use o atributo Visualizador de dados do NoSQL Workbench.