DynamoDB를 온라인 상점용 데이터 스토어로 사용 - Amazon DynamoDB

DynamoDB를 온라인 상점용 데이터 스토어로 사용

이 사용 사례에서는 DynamoDB를 온라인 상점(또는 온라인 매장)의 데이터 스토어로 사용하는 방법을 설명합니다.

사용 사례

온라인 매장을 통해 사용자는 다양한 제품을 둘러보고 최종적으로 구매할 수 있습니다. 생성된 청구서를 기반으로 고객은 할인 코드 또는 기프트 카드를 사용하여 결제한 후 나머지 금액을 신용 카드로 결제할 수 있습니다. 구매한 제품은 여러 창고 중 한 곳에서 픽업되어 제공된 주소로 배송됩니다. 온라인 매장의 일반적인 액세스 패턴은 다음과 같습니다.

  • 지정된 customerId의 고객 가져오기

  • 지정된 productId의 제품 가져오기

  • 지정된 warehouseId의 창고 가져오기

  • productId를 기준으로 모든 창고의 제품 재고 가져오기

  • 지정된 orderId의 주문 가져오기

  • 지정된 orderId의 모든 제품 가져오기

  • 지정된 orderId의 청구서 가져오기

  • 지정된 orderId의 모든 배송물 가져오기

  • 지정된 날짜 범위에서 지정된 productId의 모든 주문 가져오기

  • 지정된 invoiceId의 청구서 가져오기

  • 지정된 invoiceId에 대한 모든 결제 가져오기

  • 지정된 shipmentId의 배송 세부 정보 가져오기

  • 지정된 warehouseId의 모든 배송물 가져오기

  • 지정된 warehouseId의 모든 제품 재고 가져오기

  • 지정된 날짜 범위의 특정 customerId에 대한 모든 청구서 가져오기

  • 지정된 날짜 범위의 특정 customerId가 주문한 모든 제품 가져오기

엔터티 관계 다이어그램

다음은 DynamoDB를 온라인 상점용 데이터 스토어로 모델링하는 데 사용할 엔터티 관계 다이어그램(ERD)입니다.

제품, 주문, 결제, 고객 등의 엔터티를 포함하는 온라인 저장소의 데이터 모델에 대한 ERD.

액세스 패턴

DynamoDB를 온라인 상점의 데이터 스토어로 사용할 때 고려할 액세스 패턴은 다음과 같습니다.

  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

스키마 설계 진화

DynamoDB용 NoSQL Workbench를 사용하여 AnOnlineShop_1.json을 가져와 AnOnlineShop이라는 새 데이터 모델과 OnlineShop이라는 새 테이블을 생성합니다. 파티션 키와 정렬 키에는 일반 이름 PKSK를 사용합니다. 이는 동일한 테이블에 다양한 유형의 엔터티를 저장하기 위해 사용되는 방법입니다.

1단계: 액세스 패턴 1(getCustomerByCustomerId) 처리

AnOnlineShop_2.json을 가져와 액세스 패턴 1(getCustomerByCustomerId)을 처리합니다. 일부 엔터티는 다른 엔터티와 관계가 없으므로 해당 엔터티에 대해 동일한 PKSK 값을 사용합니다. 예제 데이터에서 키는 나중에 추가될 다른 엔터티와 customerId를 구별하기 위해 접두사 c#을 사용합니다. 이 방법은 다른 엔티티에 대해서도 반복됩니다.

이 액세스 패턴을 처리하기 위해 GetItem 작업을 PK=customerIdSK=customerId와 함께 사용할 수 있습니다.

2단계: 액세스 패턴 2(getProductByProductId) 처리

AnOnlineShop_3.json을 가져와 product 엔터티에 대한 액세스 패턴 2(getProductByProductId)를 처리합니다. 제품 엔터티에는 접두사 p#이 붙고 동일한 정렬 키 속성이 customerIDproductID를 저장하는 데 사용되었습니다. 일반 이름 지정 및 수직 파티셔닝을 통해 효과적인 단일 테이블 설계를 위한 항목 컬렉션을 생성할 수 있습니다.

이 액세스 패턴을 처리하기 위해 GetItem 작업을 PK=productIdSK=productId와 함께 사용할 수 있습니다.

3단계: 액세스 패턴 3(getWarehouseByWarehouseId) 처리

AnOnlineShop_4.json을 가져와 warehouse 엔터티에 대한 액세스 패턴 3(getWarehouseByWarehouseId)을 처리합니다. 현재 동일한 테이블에 customer, productwarehouse 엔터티가 추가되어 있습니다. 이들은 접두사와 EntityType 속성을 사용하여 구별됩니다. 유형 속성(또는 접두사 이름 지정)은 모델의 가독성을 향상시킵니다. 동일한 속성에 서로 다른 엔터티에 대한 영숫자 ID를 저장하면 가독성에 영향을 미칩니다. 이러한 식별자가 없으면 한 엔터티와 다른 엔터티를 구별하기가 어려울 수 있습니다.

이 액세스 패턴을 처리하기 위해 GetItem 작업을 PK=warehouseIdSK=warehouseId와 함께 사용할 수 있습니다.

기본 테이블:

웨어하우스 데이터를 ID별로 가져오기 위한 접두사와 EntityType이 포함된 DynamoDB 테이블 설계.

4단계: 액세스 패턴 4(getProductInventoryByProductId) 처리

AnOnlineShop_5.json을 가져와 액세스 패턴 4(getProductInventoryByProductId)를 처리합니다. warehouseItem 엔터티는 각 창고의 제품 수를 추적하는 데 사용됩니다. 이 항목은 일반적으로 제품이 창고에서 추가되거나 제거될 때 업데이트됩니다. ERD에서 볼 수 있듯이 productwarehouse 간에는 다대다 관계가 있습니다. 여기서는 product에서 warehouse로의 일대다 관계를 warehouseItem으로 모델링합니다. 나중에 warehouse에서 product로의 일대다 관계도 모델링합니다.

액세스 패턴 4는 PK=ProductIdSK begins_with “w#“에 대한 쿼리를 통해 처리될 수 있습니다.

begins_with() 및 정렬 키에 적용할 수 있는 기타 표현식에 대한 자세한 내용은 키 조건 표현식을 참조하세요.

기본 테이블:

해당 웨어하우스의 제품 인벤토리를 추적하기 위해 ProductID 및 WarehouseID를 쿼리하는 테이블 설계.

5단계: 액세스 패턴 5(getOrderDetailsByOrderId) 및 6(getProductByOrderId) 처리

AnOnlineShop_6.json을 가져와 테이블에 더 많은 customer, productwarehouse를 추가합니다. 그런 다음 AnOnlineShop_7.json을 가져와 액세스 패턴 5(getOrderDetailsByOrderId) 및 6(getProductByOrderId)을 처리할 수 있도록 order에 대한 항목 컬렉션을 생성합니다. orderItem 엔터티로 모델링된 orderproduct 간의 일대다 관계를 볼 수 있습니다.

액세스 패턴 5(getOrderDetailsByOrderId)를 처리하기 위해 PK=orderId를 사용하여 테이블을 쿼리합니다. 그러면 customerId 및 주문한 제품을 포함하여 주문에 대한 모든 정보가 제공됩니다.

기본 테이블:

주문한 모든 제품에 대한 정보를 가져오기 위해 orderId를 사용하여 쿼리하는 테이블 설계.

액세스 패턴 6(getProductByOrderId)을 해결하려면 order의 제품만 읽어야 합니다. 이를 위해 PK=orderIdSK begins_with “p#”을 사용하여 테이블을 쿼리합니다.

기본 테이블:

주문 제품을 가져오기 위해 orderId 및 productId를 사용하여 쿼리하는 테이블 설계.

6단계: 액세스 패턴 7(getInvoiceByOrderId) 처리

AnOnlineShop_8.json을 가져와 주문 항목 컬렉션에 invoice 엔터티를 추가하고 액세스 패턴 7(getInvoiceByOrderId)을 처리합니다. 이 액세스 패턴을 처리하기 위해 쿼리 작업을 PK=orderIdSK begins_with “i#”과 함께 사용할 수 있습니다.

기본 테이블:

orderID별 인보이스를 가져오기 위해 주문 항목 컬렉션에 인보이스 엔터티가 포함된 테이블 설계.

7단계: 액세스 패턴 8(getShipmentByOrderId) 처리

AnOnlineShop_9.json을 가져와 주문 항목 컬렉션에 shipment 엔터티를 추가하여 액세스 패턴 8(getShipmentByOrderId)을 처리합니다. 단일 테이블 설계에 더 많은 유형의 엔터티를 추가하여 동일한 수직 파티셔닝 모델을 확장하고 있습니다. 주문 항목 컬렉션에 포함된 order 엔터티가 shipment, orderIteminvoice 엔터티와 갖는 다양한 관계를 확인해 보세요.

orderId를 기준으로 배송물을 가져오기 위해 PK=orderIdSK begins_with “sh#”을 사용하여 쿼리 작업을 수행할 수 있습니다.

기본 테이블:

주문 ID별 배송을 가져오기 위해 주문 항목 컬렉션에 배송 엔터티가 추가된 테이블 설계.

8단계: 액세스 패턴 9(getOrderByProductIdForDateRange) 처리

이전 단계에서 주문 항목 컬렉션을 만들었습니다. 이 액세스 패턴에는 전체 테이블을 스캔하고 관련 레코드를 필터링하여 대상 항목을 가져와야 하는 새로운 조회 차원(ProductIDDate)이 있습니다. 이 액세스 패턴을 처리하려면 글로벌 보조 인덱스(GSI)를 생성해야 합니다. AnOnlineShop_10.json을 가져와 여러 주문 항목 컬렉션에서 orderItem 데이터를 검색할 수 있는 GSI를 사용하여 새 항목 컬렉션을 만듭니다. 이제 데이터에는 각각 GSI1의 파티션 키와 정렬 키가 될 GSI1-PKGSI1-SK가 있습니다.

DynamoDB는 GSI의 주요 속성이 포함된 항목을 테이블에서 GSI에 자동으로 채웁니다. GSI에 추가 삽입을 수동으로 수행할 필요가 없습니다.

액세스 패턴 9를 처리하려면 GSI1-PK=productIdGSI1SK between (date1, date2)를 사용하여 GSI1에 대해 쿼리를 수행합니다.

기본 테이블:

여러 주문 항목 컬렉션에서 주문 데이터를 가져오도록 GSI를 사용한 테이블 설계.

GSI1:

제품 ID 및 날짜별 주문을 가져오기 위해 ProductID 및 Date를 파티션 키와 정렬 키로 사용하는 GSI 설계.

9단계: 액세스 패턴 10(getInvoiceByInvoiceId) 및 11(getPaymentByInvoiceId) 처리

AnOnlineShop_11.json을 가져와서 invoice와 관련된 액세스 패턴 10(getInvoiceByInvoiceId) 및 11(getPaymentByInvoiceId)을 처리합니다. 이는 서로 다른 두 가지 액세스 패턴이지만 동일한 키 조건을 사용하여 구현됩니다. Paymentsinvoice 엔터티에 대한 맵 데이터 유형의 속성으로 정의됩니다.

참고

GSI1-PKGSI1-SK는 여러 엔터티에 대한 정보를 저장하도록 오버로드되므로 동일한 GSI에서 여러 액세스 패턴을 제공할 수 있습니다. GSI 오버로딩에 대한 자세한 내용은 글로벌 보조 인덱스 오버로딩 섹션을 참조하세요.

액세스 패턴 10 및 11을 처리하려면 GSI1-PK=invoiceIdGSI1-SK=invoiceId를 사용하여 GSI1에 대해 쿼리를 수행합니다.

GSI1:

인보이스 ID별로 인보이스 및 결제를 가져오기 위해 invoiceID를 파티션 키와 정렬 키로 사용하는 GSI 설계.

10단계: 액세스 패턴 12(getShipmentDetailsByShipmentId) 및 13(getShipmentByWarehouseId) 처리

AnOnlineShop_12.json을 가져와 액세스 패턴 12(getShipmentDetailsByShipmentId) 및 13(getShipmentByWarehouseId)을 처리합니다.

단일 쿼리 작업으로 주문에 대한 모든 세부 정보를 검색할 수 있도록 shipmentItem 엔터티가 기본 테이블의 주문 항목 컬렉션에 추가됩니다.

기본 테이블:

모든 주문 세부 정보를 가져오기 위해 주문 항목 컬렉션에 shipmentItem 엔터티가 포함된 테이블 설계.

GSI1 파티션 및 정렬 키는 이미 shipmentshipmentItem 간의 일대다 관계를 모델링하는 데 사용되었습니다. 액세스 패턴 12(getShipmentDetailsByShipmentId)를 처리하려면 GSI1-PK=shipmentIdGSI1-SK=shipmentId를 사용하여 GSI1에 대해 쿼리를 수행합니다.

GSI1:

배송 ID별로 배송 세부 정보를 가져오기 위해 shipmentId를 파티션 키 및 정렬 키로 사용하는 GSI1 설계.

액세스 패턴 13(getShipmentByWarehouseId)에 대해 warehouseshipment 간의 새로운 일대다 관계를 모델링하려면 또 다른 GSI(GSI2)를 만들어야 합니다. 이 액세스 패턴을 처리하려면 GSI2-PK=warehouseIdGSI2-SK begins_with “sh#”를 사용하여 GSI2에 대해 쿼리를 수행합니다.

GSI2:

창고별 배송물을 가져오기 위해 warehouseId 및 shipmentId를 파티션 키와 정렬 키로 사용하는 GSI2 설계.

11: 액세스 패턴 14(getProductInventoryByWarehouseId) 15(getInvoiceByCustomerIdForDateRange) 및 16(getProductsByCustomerIdForDateRange) 처리

AnOnlineShop_13.json을 가져와서 다음 액세스 패턴 세트와 관련된 데이터를 추가합니다. 액세스 패턴 14(getProductInventoryByWarehouseId)를 처리하려면 GSI2-PK=warehouseIdGSI2-SK begins_with “p#”를 사용하여 GSI2에 대해 쿼리를 수행합니다.

GSI2:

액세스 패턴 14를 처리하기 위해 warehouseId 및 productId를 파티션 키와 정렬 키로 사용하는 GSI2 설계.

액세스 패턴 15(getInvoiceByCustomerIdForDateRange)를 처리하려면 GSI2-PK=customerIdGSI2-SK between (i#date1, i#date2)를 사용하여 GSI2에 대해 쿼리를 수행합니다.

GSI2:

액세스 패턴 15를 처리하기 위해 customerId 및 인보이스 날짜 범위를 파티션 키와 정렬 키로 사용하는 GSI2 설계.

액세스 패턴 16(getProductsByCustomerIdForDateRange)을 처리하려면 GSI2-PK=customerIdGSI2-SK between (p#date1, p#date2)를 사용하여 GSI2에 대해 쿼리를 수행합니다.

GSI2:

액세스 패턴 16을 처리하기 위해 customerId 및 제품 날짜 범위를 파티션 키와 정렬 키로 사용하는 GSI2 설계.
참고

NoSQL Workbench에서 패싯은 애플리케이션의 서로 다른 DynamoDB 데이터 액세스 패턴을 나타냅니다. 패싯을 사용하면 패싯의 제약 조건을 충족하지 않는 레코드를 확인할 필요 없이 테이블에서 데이터의 하위 집합을 볼 수 있습니다. 패싯은 시각적 데이터 모델링 도구로 간주되며 DynamoDB에서 사용 가능한 구성체로 존재하지 않습니다. 패싯은 순전히 액세스 패턴 모델링에 도움이 되기 때문입니다.

AnOnlineShop_facets.json을 가져와 이 사용 사례의 패싯을 확인합니다.

모든 액세스 패턴과 스키마 설계에서 이를 처리하는 방법이 아래 표에 요약되어 있습니다.

액세스 패턴 기본 테이블/GSI/LSI Operation 파티션 키 값 정렬 키 값
getCustomerByCustomerId 기본 테이블 GetItem PK=customerId SK=customerId
getProductByProductId 기본 테이블 GetItem PK=productId SK=productId
getWarehouseByWarehouseId 기본 테이블 GetItem PK=warehouseId SK=warehouseId
getProductInventoryByProductId 기본 테이블 쿼리 PK=productId SK begins_with "w#"
getOrderDetailsByOrderId 기본 테이블 쿼리 PK=orderId
getProductByOrderId 기본 테이블 쿼리 PK=orderId SK begins_with "p#"
getInvoiceByOrderId 기본 테이블 쿼리 PK=orderId SK begins_with "i#"
getShipmentByOrderId 기본 테이블 쿼리 PK=orderId SK begins_with "sh#"
getOrderByProductIdForDateRange GSI1 Query PK=productId SK between date1 and date2
getInvoiceByInvoiceId GSI1 Query PK=invoiceId SK=invoiceId
getPaymentByInvoiceId GSI1 Query PK=invoiceId SK=invoiceId
getShipmentDetailsByShipmentId GSI1 Query PK=shipmentId SK=shipmentId
getShipmentByWarehouseId GSI2 Query PK=warehouseId SK begins_with "sh#"
getProductInventoryByWarehouseId GSI2 Query PK=warehouseId SK begins_with "p#"
getInvoiceByCustomerIdForDateRange GSI2 Query PK=customerId SK between i#date1 and i#date2
getProductsByCustomerIdForDateRange GSI2 Query PK=customerId SK between p#date1 and p#date2

온라인 상점 최종 스키마

다음은 최종 스키마 설계입니다. 이 스키마 설계를 JSON 파일로 다운로드하려면 GitHub의 DynamoDB 설계 패턴을 참조하세요.

기본 테이블

EntityName 및 Name과 같은 속성이 있는 온라인 쇼핑몰용 기본 테이블의 최종 스키마.

GSI1

EntityType과 같은 속성이 있는 온라인 쇼핑몰 기본 테이블의 최종 GSI1 스키마.

GSI2

EntityType과 같은 속성이 있는 온라인 쇼핑몰 기본 테이블의 최종 GSI2 스키마.

이 스키마 설계와 함께 NoSQL Workbench 사용

이 최종 스키마를 DynamoDB 데이터 모델링, 데이터 시각화, 쿼리 개발 기능을 제공하는 시각적 도구인 NoSQL Workbench로 가져와서 새 프로젝트를 추가로 탐색하고 편집할 수 있습니다. 시작하려면 다음 단계를 따릅니다.

  1. NoSQL Workbench 다운로드 자세한 내용은 DynamoDB용 NoSQL Workbench 다운로드 단원을 참조하십시오.

  2. 위에 나열된 JSON 스키마 파일을 다운로드합니다. 이 파일은 이미 NoSQL Workbench 모델 형식으로 되어 있습니다.

  3. JSON 스키마 파일을 NoSQL Workbench로 가져옵니다. 자세한 내용은 기존 데이터 모델 가져오기 단원을 참조하십시오.

  4. NOSQL Workbench로 가져온 후 데이터 모델을 편집할 수 있습니다. 자세한 내용은 기존 데이터 모델 편집 단원을 참조하십시오.

  5. 데이터 모델을 시각화하거나, 샘플 데이터를 추가하거나, CSV 파일에서 샘플 데이터를 가져오려면 NoSQL Workbench의 Data Visualizer 기능을 사용하세요.