

# Usar o DynamoDB como armazenamento de dados para uma loja virtual
<a name="data-modeling-online-shop"></a>

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
<a name="data-modeling-schema-online-shop"></a>

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
<a name="data-modeling-schema-online-shop-erd"></a>

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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-1-ERD.png)


## Padrões de acesso
<a name="data-modeling-schema-online-shop-access-patterns"></a>

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

1. `getCustomerByCustomerId`

1. `getProductByProductId`

1. `getWarehouseByWarehouseId`

1. `getProductInventoryByProductId`

1. `getOrderDetailsByOrderId`

1. `getProductByOrderId`

1. `getInvoiceByOrderId`

1. `getShipmentByOrderId`

1. `getOrderByProductIdForDateRange`

1. `getInvoiceByInvoiceId`

1. `getPaymentByInvoiceId`

1. `getShipmentDetailsByShipmentId`

1. `getShipmentByWarehouseId`

1. `getProductInventoryByWarehouseId`

1. `getInvoiceByCustomerIdForDateRange`

1. `getProductsByCustomerIdForDateRange`

## Evolução do design do esquema
<a name="data-modeling-schema-online-shop-design-evolution"></a>

Usando [NoSQL Workbench para DynamoDB](workbench.md), importe [AnOnlineShop\_1.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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 [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) com `PK=customerId` e `SK=customerId`.

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

Importe [AnOnlineShop\_3.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) 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](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-2-Step3.png)


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

Importe [AnOnlineShop\_5.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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](Query.KeyConditionExpressions.md).

**Tabela base:**

![Design de tabela para consultar ProductID e warehouseId para rastrear o estoque de produtos em determinado depósito.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-3-Step4.png)


**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](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_6.json). Depois, importe [AnOnlineShop\_7.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-4-Step5.png)


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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-5-Step5.png)


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

Importe [AnOnlineShop\_8.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-6-Step6.png)


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

Importe [AnOnlineShop\_9.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-7-Step7.png)


**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)](GSI.md). Importe [AnOnlineShop\_10.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-8-Step8-Base.png)


**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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-9-Step8-GSI.png)


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

Importe [AnOnlineShop\_11.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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](bp-gsi-overloading.md).

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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-10-Step9.png)


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

Importe [AnOnlineShop\_12.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-11-Step10.png)


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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-12-Step10-GSI.png)


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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-13-Step10-GSI2.png)


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

Importe [AnOnlineShop\_13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-14-Step11-GSI2.png)


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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-15-Step11-GSI2.png)


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.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-16-Step11-GSI2.png)


**nota**  
No [NoSQL Workbench](workbench.md), 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](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/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
<a name="data-modeling-schema-online-store-final-schema"></a>

Veja aqui os designs do esquema final. Para baixar esse design de esquema como arquivo JSON, consulte [Padrões de design do DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) no GitHub.

**Tabela base**

![Esquema final da tabela base para uma loja on-line com atributos, como EntityName e Name.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-17-Final-BaseTable.png)


**GSI1**

![Esquema de GSI1 final para a tabela base de uma loja on-line com atributos, como EntityType.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-18-Final-GSI1.png)


**GSI2**

![Esquema de GSI2 final para a tabela base de uma loja on-line com atributos, como EntityType.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-19-Final-GSI2.png)


## Como usar o NoSQL Workbench com esse design de esquema
<a name="data-modeling-schema-online-shop-nosql"></a>

Você pode importar esse esquema final para o [NoSQL Workbench](workbench.md), 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 obter mais informações, consulte [Baixar o NoSQL Workbench para DynamoDB](workbench.settingup.md).

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

1. Importe o arquivo do esquema JSON para o NoSQL Workbench. Para obter mais informações, consulte [Importar um modelo de dados existente](workbench.Modeler.ImportExisting.md). 

1. Depois de importar para o NOSQL Workbench, você pode editar o modelo de dados. Para obter mais informações, consulte [Editar um modelo de dados existente](workbench.Modeler.Edit.md).