Uso de DynamoDB como almacén de datos para una tienda en línea
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
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
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.
Patrones de acceso
Estos son los patrones de acceso que tendremos en cuenta al utilizar DynamoDB como almacén de datos para una tienda en línea.
-
getCustomerByCustomerId
-
getProductByProductId
-
getWarehouseByWarehouseId
-
getProductInventoryByProductId
-
getOrderDetailsByOrderId
-
getProductByOrderId
-
getInvoiceByOrderId
-
getShipmentByOrderId
-
getOrderByProductIdForDateRange
-
getInvoiceByInvoiceId
-
getPaymentByInvoiceId
-
getShipmentDetailsByShipmentId
-
getShipmentByWarehouseId
-
getProductInventoryByWarehouseId
-
getInvoiceByCustomerIdForDateRange
-
getProductsByCustomerIdForDateRange
Evolución del diseño de esquema
Mediante NoSQL Workbench para DynamoDB, importe AnOnlineShop_1.jsonAnOnlineShop
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_2.jsongetCustomerByCustomerId
). 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 GetItem
con PK=customerId
y SK=customerId
.
Paso 2: Abordar el patrón de acceso 2 (getProductByProductId
)
Importe AnOnlineShop_3.jsongetProductByProductId
) 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 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_4.jsongetWarehouseByWarehouseId
) 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:
Paso 4: Abordar el patrón de acceso 4 (getProductInventoryByProductId
)
Importe AnOnlineShop_5.jsongetProductInventoryByProductId
). 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.
Tabla base:
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_6.jsonorder
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:
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:
Paso 6: Abordar el patrón de acceso 7 (getInvoiceByOrderId
)
Importe AnOnlineShop_8.jsoninvoice
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:
Paso 7: Abordar el patrón de acceso 8 (getShipmentByOrderId
)
Importe AnOnlineShop_9.jsonshipment
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:
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). Importe AnOnlineShop_10.jsonorderItem
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:
GSI1:
Paso 9: Abordar patrones de acceso 10 (getInvoiceByInvoiceId
) y 11 (getPaymentByInvoiceId
)
Importe AnOnlineShop_11.jsongetInvoiceByInvoiceId
) 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.
Para abordar los patrones de acceso 10 y 11, realice una consulta de GSI1
con GSI1-PK=invoiceId
y GSI1-SK=invoiceId
.
GSI1:
Paso 10: Abordar patrones de acceso 12 (getShipmentDetailsByShipmentId
) y 13 (getShipmentByWarehouseId
)
Importe AnOnlineShop_12.jsongetShipmentDetailsByShipmentId
) 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:
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:
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:
Paso 11: Abordar patrones de acceso 14 (getProductInventoryByWarehouseId
), 15 (getInvoiceByCustomerIdForDateRange
) y 16 (getProductsByCustomerIdForDateRange
)
Importe AnOnlineShop_13.jsongetProductInventoryByWarehouseId
), realice una consulta de GSI2
con GSI2-PK=warehouseId
y GSI2-SK
begins_with “p#”
.
GSI2:
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:
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:
nota
En NoSQL Workbench, 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_facets.json
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 base | Consultar | PK=productId | SK begins_with “w#” |
getOrderDetailsByOrderId | Tabla base | Consultar | PK=orderId | |
getProductByOrderId | Tabla base | Consultar | PK=orderId | SK begins_with “p#” |
getInvoiceByOrderId | Tabla base | Consultar | PK=orderId | SK begins_with “i#” |
getShipmentByOrderId | Tabla base | Consultar | PK=orderId | SK begins_with “sh#” |
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_with “sh#” |
getProductInventoryByWarehouseId | GSI2 | Consultar | PK=warehouseId | SK begins_with “p#” |
getInvoiceByCustomerIdForDateRange | GSI2 | Consultar | PK=customerId | SK between i#date1 and i#date2 |
getProductsByCustomerIdForDateRange | GSI2 | Consultar | PK=customerId | SK between p#date1 and p#date2 |
Esquema final de la tienda en línea
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
Tabla base
GSI1
GSI2
Uso de NoSQL Workbench con este diseño de esquema
Puede importar este esquema final en NoSQL Workbench, 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:
-
Descargue NoSQL Workbench. Para obtener más información, consulte Descargar NoSQL Workbench para DynamoDB.
-
Descargue el archivo de esquema JSON que se muestra anteriormente, que ya está en el formato de modelo NoSQL Workbench.
-
Importe el archivo de esquema JSON en NoSQL Workbench. Para obtener más información, consulte Importación de un modelo de datos existente.
-
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.
-
Para visualizar el modelo de datos, agregar datos de ejemplo o importar datos de ejemplo de un archivo CSV, utilice la característica Visualizador de datos de NoSQL Workbench.