

# Uso de DynamoDB como almacén de datos para una tienda en línea
<a name="data-modeling-online-shop"></a>

En este caso de uso se habla de utilizar DynamoDB como almacén de datos para una tienda en línea (o tienda electrónica).

## Caso de uso
<a name="data-modeling-schema-online-shop"></a>

Una tienda en línea permite a los usuarios navegar por diferentes productos y, finalmente, comprarlos. Basándose en la factura generada, el cliente puede pagar utilizando un código de descuento o una tarjeta regalo y, a continuación, abonar el importe restante con una tarjeta de crédito. Los productos adquiridos se retirarán de uno de varios almacenes y se enviarán a la dirección facilitada. Los patrones de acceso típicos de una tienda en línea incluyen:
+ Obtener el cliente para un customerId dado
+ Obtener el producto para un productId dado
+ Obtener almacén para un warehouseId dado
+ Obtener un inventario de productos para todos los almacenes por un productId
+ Obtener pedido para un orderId dado
+ Obtener todos los productos para un orderId dado
+ Obtener la factura de un orderId dado
+ Obtener todos los envíos para un orderId dado
+ Obtener todos los pedidos de un productId determinado para un intervalo de fechas dado
+ Obtener la factura para un invoiceId dado
+ Obtener todos los pagos para un invoiceId dado
+ Obtener los detalles de envío para un shipmentId dado
+ Obtener todos los envíos para un warehouseId dado
+ Obtener el inventario de todos los productos para un warehouseId dado
+ Obtener todas las facturas de un customerId determinado para un intervalo de fechas dado
+ Obtener todos los productos pedidos por un customerId determinado para un intervalo de fechas dado

## Diagrama de relaciones entre entidades
<a name="data-modeling-schema-online-shop-erd"></a>

Este es el diagrama de relaciones entre entidades (ERD) que utilizaremos para modelar DynamoDB como almacén de datos para una tienda en línea.

![\[ERD para un modelo de datos de almacenamiento en línea con entidades como el producto, el pedido, el pago y el cliente.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-1-ERD.png)


## Patrones de acceso
<a name="data-modeling-schema-online-shop-access-patterns"></a>

Estos son los patrones de acceso que tendremos en cuenta al utilizar DynamoDB como almacén de datos para una tienda en línea.

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`

## Evolución del diseño de esquema
<a name="data-modeling-schema-online-shop-design-evolution"></a>

Mediante [NoSQL Workbench para DynamoDB](workbench.md), importe [AnOnlineShop\$11.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_1.json) para crear un nuevo modelo de datos llamado `AnOnlineShop` y una nueva tabla llamada `OnlineShop`. Tenga en cuenta que utilizamos los nombres genéricos `PK` y `SK` para la clave de partición y la clave de clasificación. Se trata de una práctica utilizada para almacenar distintos tipos de entidades en la misma tabla.

**Paso 1: Abordar el patrón de acceso 1 (`getCustomerByCustomerId`)**

Importe [AnOnlineShop\$12.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_2.json) para gestionar el patrón de acceso 1 (`getCustomerByCustomerId`). Algunas entidades no tienen relaciones con otras entidades, por lo que utilizaremos el mismo valor de `PK` y `SK` para ellas. En los datos del ejemplo, observe que las claves utilizan un prefijo `c#` para distinguir `customerId` de otras entidades que se agregarán posteriormente. Esta práctica se repite también para otras entidades. 

Para abordar este patrón de acceso, se puede utilizar una operación [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) con `PK=customerId` y `SK=customerId`.

**Paso 2: Abordar el patrón de acceso 2 (`getProductByProductId`)**

Importe [AnOnlineShop\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_3.json) para abordar el patrón de acceso 2 (`getProductByProductId`) para la entidad `product`. Las entidades de producto tienen el prefijo `p#` y se ha utilizado el mismo atributo de clave de clasificación para almacenar `customerID` y `productID`. La denominación genérica y la [partición vertical](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) nos permiten crear tales colecciones de elementos para un diseño eficaz de tabla única. 

Para abordar este patrón de acceso, se puede utilizar una operación `GetItem` con `PK=productId` y `SK=productId`.

**Paso 3: Abordar el patrón de acceso 3 (`getWarehouseByWarehouseId`)**

Importe [AnOnlineShop\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_4.json) para abordar el patrón de acceso 3 (`getWarehouseByWarehouseId`) para la entidad `warehouse`. Actualmente tenemos las entidades `customer`, `product` y `warehouse` agregadas a la misma tabla. Se distinguen mediante prefijos y el atributo `EntityType`. Un atributo de tipo (o prefijo de nomenclatura) mejora la legibilidad del modelo. La legibilidad se vería afectada si simplemente almacenáramos ID alfanuméricos para diferentes entidades en el mismo atributo. Sería difícil distinguir una entidad de otra en ausencia de estos identificadores. 

Para abordar este patrón de acceso, se puede utilizar una operación `GetItem` con `PK=warehouseId` y `SK=warehouseId`.

**Tabla base:**

![\[Diseño de tabla de DynamoDB con prefijos y EntityType para obtener los datos del almacén por su ID.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-2-Step3.png)


**Paso 4: Abordar el patrón de acceso 4 (`getProductInventoryByProductId`)**

Importe [AnOnlineShop\$15.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_5.json) para abordar el patrón de acceso 4 (`getProductInventoryByProductId`). La entidad `warehouseItem` se utiliza para realizar un seguimiento del número de productos de cada almacén. Este elemento se actualizará normalmente cuando se agregue o elimine un producto de un almacén. Como se ve en el ERD, existe una relación de varios a varios entre `product` y `warehouse`. Aquí, la relación de uno a varios de `product` a `warehouse` se modela como `warehouseItem`. Más adelante, también se modelará la relación de uno a varios de `warehouse` a `product`. 

El patrón de acceso 4 puede abordarse con una consulta sobre `PK=ProductId` y `SK begins_with “w#“`. 

Para obtener más información sobre `begins_with()` y otras expresiones que pueden aplicarse a las claves de clasificación, consulte [Expresiones de condición de clave](Query.KeyConditionExpressions.md).

**Tabla base:**

![\[Diseño de tabla para consultar ProductID y WarehouseID para rastrear el inventario de productos en un almacén determinado.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-3-Step4.png)


**Paso 5: Abordar patrones de acceso 5 (`getOrderDetailsByOrderId`) y 6 (`getProductByOrderId`)**

Agregue más elementos `customer`, `product` y `warehouse` a la tabla mediante la importación de [AnOnlineShop\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_6.json). A continuación, importe [AnOnlineShop\$17.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_7.json) para crear una colección de elementos a fin de que `order` pueda abordar los patrones de acceso 5 (`getOrderDetailsByOrderId`) y 6 (`getProductByOrderId`). Puede ver la relación de uno a varios entre `order` y `product` modelada como entidades orderItem. 

Para abordar el patrón de acceso 5 (`getOrderDetailsByOrderId`), consulte la tabla con `PK=orderId`. Esto le proporcionará toda la información sobre el pedido, incluidos `customerId` y los productos solicitados.

**Tabla base:**

![\[Diseño de tabla para realizar consultas mediante OrderID para obtener información sobre todos los productos pedidos.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-4-Step5.png)


Para abordar el patrón de acceso 6 (`getProductByOrderId`), necesitamos leer los productos en un `order` solamente. Consulte la tabla con `PK=orderId` y `SK begins_with “p#”` para conseguirlo.

**Tabla base:**

![\[Diseño de tabla para realizar consultas mediante OrderID y ProductID para obtener los productos de un pedido.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-5-Step5.png)


**Paso 6: Abordar el patrón de acceso 7 (`getInvoiceByOrderId`)**

Importe [AnOnlineShop\$18.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_8.json) para agregar una entidad `invoice` a la colección de elementos de *pedido* para gestionar el patrón de acceso 7 (`getInvoiceByOrderId`). Para abordar este patrón de acceso, puede utilizar una operación de consulta con `PK=orderId` y `SK begins_with “i#”`.

**Tabla base:**

![\[Diseño de tabla con la entidad de la factura en la recopilación de artículos del pedido para obtener una factura por OrderID.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-6-Step6.png)


**Paso 7: Abordar el patrón de acceso 8 (`getShipmentByOrderId`)**

Importe [AnOnlineShop\$19.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_9.json) para agregar entidades `shipment` a la colección de elementos de *pedido* para abordar el patrón de acceso 8 (`getShipmentByOrderId`). Estamos ampliando el mismo modelo particionado verticalmente mediante la adición de más tipos de entidades en un diseño de tabla única. Observe cómo la colección de elementos de *pedido* contiene las distintas relaciones que una entidad `order` tiene con las entidades `shipment`, `orderItem` y `invoice`. 

Para obtener envíos por `orderId`, puede realizar una operación de consulta con `PK=orderId` y `SK begins_with “sh#”`.

**Tabla base:**

![\[Diseño de tabla con la entidad de envío agregada a la recopilación de artículos del pedido para obtener los envíos por ID de pedido.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-7-Step7.png)


**Paso 8: Abordar el patrón de acceso 9 (`getOrderByProductIdForDateRange`)**

Hemos creado una colección de elementos de *pedido* en el paso anterior. Este patrón de acceso tiene nuevas dimensiones de búsqueda (`ProductID` y `Date`) que le obligan a escanear toda la tabla y filtrar los registros relevantes para obtener los elementos buscados. Para abordar este patrón de acceso, necesitaremos crear un [índice secundario global (GSI)](GSI.md). Importe [AnOnlineShop\$110.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_10.json) para crear una nueva colección de elementos mediante el GSI que permite recuperar datos `orderItem` de varias colecciones de elementos de *pedido*. Los datos tienen ahora `GSI1-PK` y `GSI1-SK`, que serán la clave de partición y la clave de clasificación de `GSI1`, respectivamente. 

DynamoDB rellena automáticamente los elementos que contienen los atributos clave de un GSI desde la tabla al GSI. No es necesario realizar manualmente ninguna inserción adicional en el GSI. 

Para abordar el patrón de acceso 9, realice una consulta de `GSI1` con `GSI1-PK=productId` y `GSI1SK between (date1, date2)`.

**Tabla base:**

![\[Diseño de tabla con un GSI para obtener datos de pedidos de varias recopilaciones de artículos de pedidos.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-8-Step8-Base.png)


**GSI1:**

![\[Diseño de GSI con ProductID y Fecha como claves de partición y clasificación para obtener pedidos por ID de producto y fecha.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-9-Step8-GSI.png)


**Paso 9: Abordar patrones de acceso 10 (`getInvoiceByInvoiceId`) y 11 (`getPaymentByInvoiceId`)**

Importe [AnOnlineShop\$111.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_11.json) para abordar los patrones de acceso 10 (`getInvoiceByInvoiceId`) y 11 (`getPaymentByInvoiceId`), ambos relacionados con `invoice`. Aunque se trata de dos patrones de acceso diferentes, se realizan con la misma condición clave. `Payments` se definen como un atributo con el tipo de datos de asignación en la entidad `invoice`.

**nota**  
`GSI1-PK` y `GSI1-SK` se sobrecargan para almacenar información sobre diferentes entidades, de forma que se puedan servir múltiples patrones de acceso desde el mismo GSI. Para obtener más información sobre la sobrecarga de GSI, consulte [Sobrecarga de índices secundarios globales en DynamoDB](bp-gsi-overloading.md).

Para abordar los patrones de acceso 10 y 11, realice una consulta de `GSI1` con `GSI1-PK=invoiceId` y `GSI1-SK=invoiceId`.

**GSI1:**

![\[Diseño de GSI con invoiceId como partición y clave de clasificación para obtener la factura y el pago por ID de factura.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-10-Step9.png)


**Paso 10: Abordar patrones de acceso 12 (`getShipmentDetailsByShipmentId`) y 13 (`getShipmentByWarehouseId`)**

Importe [AnOnlineShop\$112.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_12.json) para abordar los patrones de acceso 12 (`getShipmentDetailsByShipmentId`) y 13 (`getShipmentByWarehouseId`). 

Observe que se agregan entidades `shipmentItem` a la colección de elementos de *pedido* en la tabla base para poder recuperar todos los detalles sobre un pedido en una sola operación de consulta.

**Tabla base:**

![\[Diseño de tabla con la entidad shipmentItem para la recopilación de artículos del pedido para obtener todos los detalles del pedido.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-11-Step10.png)


Las claves de partición y clasificación de `GSI1` ya se han utilizado para modelar una relación de uno a varios entre `shipment` y `shipmentItem`. Para abordar el patrón de acceso 12 (`getShipmentDetailsByShipmentId`), realice una consulta de `GSI1` con `GSI1-PK=shipmentId` y `GSI1-SK=shipmentId`.

**GSI1:**

![\[Diseño de GSI1 con shipmentID como partición y clave de clasificación para obtener los detalles del envío por ID de envío.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-12-Step10-GSI.png)


Tendremos que crear otro GSI (`GSI2`) para modelar la nueva relación de uno a varios entre `warehouse` y `shipment` para el patrón de acceso 13 (`getShipmentByWarehouseId`). Para abordar este patrón de acceso, realice una consulta de `GSI2` con `GSI2-PK=warehouseId` y `GSI2-SK begins_with “sh#”`.

**GSI2:**

![\[Diseño de GSI2 con warehouseId y shipmentId como particiones y claves de clasificación para obtener los envíos por almacén.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-13-Step10-GSI2.png)


**Paso 11: Abordar patrones de acceso 14 (`getProductInventoryByWarehouseId`), 15 (`getInvoiceByCustomerIdForDateRange`) y 16 (`getProductsByCustomerIdForDateRange`)**

Importe [AnOnlineShop\$113.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_13.json) para agregar los datos relacionados con el siguiente conjunto de patrones de acceso. Para abordar el patrón de acceso 14 (`getProductInventoryByWarehouseId`), realice una consulta de `GSI2` con `GSI2-PK=warehouseId` y `GSI2-SK begins_with “p#”`.

**GSI2:**

![\[Diseño de GSI2 con warehouseId y productId como claves de partición y clasificación para abordar el patrón de acceso 14.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-14-Step11-GSI2.png)


Para abordar el patrón de acceso 15 (`getInvoiceByCustomerIdForDateRange`), realice una consulta de `GSI2` con `GSI2-PK=customerId` y `GSI2-SK between (i#date1, i#date2)`.

**GSI2:**

![\[Diseño de GSI2 con customerId y rango de fechas de la factura como partición y claves de clasificación para abordar el patrón de acceso 15.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-15-Step11-GSI2.png)


Para abordar el patrón de acceso 16 (`getProductsByCustomerIdForDateRange`), realice una consulta de `GSI2` con `GSI2-PK=customerId` y `GSI2-SK between (p#date1, p#date2)`.

**GSI2:**

![\[Diseño de GSI2 con customerId y rango de fechas del producto como partición y claves de clasificación para abordar el patrón de acceso 16\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-16-Step11-GSI2.png)


**nota**  
En [NoSQL Workbench](workbench.md), las *facetas* representan los diferentes patrones de acceso a los datos de una aplicación para DynamoDB. Las facetas le permiten ver un subconjunto de datos de una tabla, sin tener que ver registros que no cumplen las restricciones de la faceta. Las facetas se consideran una herramienta visual de modelado de datos y no existen como un constructo utilizable en DynamoDB, ya que son puramente una ayuda para modelar patrones de acceso.   
Importe [AnOnlineShop\$1facets.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_facets.json) para ver las facetas de este caso de uso.

En la tabla siguiente se resumen todos los patrones de acceso y cómo los aborda el diseño del esquema:


| Patrón de acceso | Tabla base/GSI/LSI | Operación | Valor de clave de partición | Valor de la clave de clasificación | 
| --- | --- | --- | --- | --- | 
| getCustomerByCustomerId | Tabla de base | GetItem |  PK=customerId | SK=customerId | 
| getProductByProductId | Tabla de base | GetItem |  PK=productId | SK=productId | 
| getWarehouseByWarehouseId | Tabla de base | GetItem |  PK=warehouseId | SK=warehouseId | 
| getProductInventoryByProductId | Tabla de base | Consultar |  PK=productId | SK begins\$1with “w\$1” | 
| getOrderDetailsByOrderId | Tabla de base | Consultar |  PK=orderId |  | 
| getProductByOrderId | Tabla de base | Consultar |  PK=orderId | SK begins\$1with “p\$1” | 
| getInvoiceByOrderId |  Tabla de base | Consultar |  PK=orderId | SK begins\$1with “i\$1” | 
| getShipmentByOrderId |  Tabla de base | Consultar |  PK=orderId | SK begins\$1with “sh\$1” | 
| getOrderByProductIdForDateRange |  GSI1 | Consultar |  PK=productId | SK between date1 and date2 | 
| getInvoiceByInvoiceId |  GSI1 | Consultar |  PK=invoiceId | SK=invoiceId | 
| getPaymentByInvoiceId |  GSI1 | Consultar |  PK=invoiceId | SK=invoiceId | 
| getShipmentDetailsByShipmentId |  GSI1 | Consultar |  PK=shipmentId | SK=shipmentId | 
| getShipmentByWarehouseId |  GSI2 | Consultar |  PK=warehouseId | SK begins\$1with “sh\$1” | 
| getProductInventoryByWarehouseId |  GSI2 | Consultar |  PK=warehouseId | SK begins\$1with “p\$1” | 
| getInvoiceByCustomerIdForDateRange |  GSI2 | Consultar |  PK=customerId | SK between i\$1date1 and i\$1date2 | 
| getProductsByCustomerIdForDateRange |  GSI2 | Consultar |  PK=customerId | SK between p\$1date1 and p\$1date2 | 

### Esquema final de la tienda en línea
<a name="data-modeling-schema-online-store-final-schema"></a>

Estos son los diseños finales del esquema. Para descargar este diseño de esquema como un archivo JSON, consulte [Patrones de diseño de DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) en GitHub.

**Tabla base**

![\[Esquema final de la tabla base para una tienda en línea con atributos, como EntityName y Nombre.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-17-Final-BaseTable.png)


**GSI1**

![\[Esquema de GSI1 final para una tabla base de tienda en línea con atributos, como EntityName.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-18-Final-GSI1.png)


**GSI2**

![\[Esquema de GSI2 final para una tabla base de tienda en línea con atributos, como EntityName.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-19-Final-GSI2.png)


## Uso de NoSQL Workbench con este diseño de esquema
<a name="data-modeling-schema-online-shop-nosql"></a>

Puede importar este esquema final en [NoSQL Workbench](workbench.md), una herramienta visual que proporciona características de modelado de datos, visualización de datos y desarrollo de consultas para DynamoDB, a fin de explorar y editar más a fondo el nuevo proyecto. Para comenzar, siga estos pasos:

1. Descargue NoSQL Workbench. Para obtener más información, consulte [Descargar NoSQL Workbench para DynamoDB](workbench.settingup.md).

1. Descargue el archivo de esquema JSON que se muestra anteriormente, que ya está en el formato de modelo NoSQL Workbench.

1. Importe el archivo de esquema JSON en NoSQL Workbench. Para obtener más información, consulte [Importación de un modelo de datos existente](workbench.Modeler.ImportExisting.md). 

1. Una vez que haya importado en NOSQL Workbench, podrá editar el modelo de datos. Para obtener más información, consulte [Edición de un modelo de datos existente](workbench.Modeler.Edit.md).