Bảng đơn hàng thương mại điện tử. Tiết kiệm giá, hoặc sử dụng bảng kiểm toán / lịch sử?


13

Tôi đang thiết kế lược đồ thương mại điện tử đầu tiên của tôi. Tôi đã đọc xung quanh chủ đề này một chút và hơi bối rối về mối quan hệ giữa một order_line_itemvà mộtproduct

A productcó thể được mua. Nó có nhiều chi tiết khác nhau, nhưng quan trọng nhất là unit_price.

An order_line_itemcó khóa ngoại đối với sản phẩm product_idđã mua, quantityđã mua và unit_pricetại thời điểm khách hàng mua sản phẩm.

Hầu hết những gì tôi đã đọc nói rằng unit_pricetrên order_line_itemnên được thêm một cách rõ ràng (tức là không được tham chiếu qua product_id). Có ý nghĩa, vì các cửa hàng có thể thay đổi giá trong tương lai sẽ làm rối tung các báo cáo đơn hàng, theo dõi, tính toàn vẹn, vv

Điều tôi không hiểu, là tại sao trực tiếp lưu unit_pricegiá trị vào order_line_item?

Nó sẽ không tốt hơn để tạo một bảng kiểm toán / lịch sử ghi lại unit_pricesự thay đổi của một product?

Khi một order_line_itemđược tạo, khóa ngoại của product_auditbảng được thêm vào và giá có thể được lấy (bằng cách tham chiếu) từ đó.

Dường như với tôi có rất nhiều điều tích cực khi sử dụng phương pháp này (ít trùng lặp dữ liệu, lịch sử thay đổi giá, v.v.), vậy tại sao nó không được sử dụng thường xuyên hơn? Tôi chưa bắt gặp một ví dụ về lược đồ thương mại điện tử sử dụng phương pháp này, tôi có thiếu điều gì không?

UDPATE: Có vẻ như câu hỏi của tôi liên quan đến Kích thước thay đổi chậm . Mặc dù vậy, tôi vẫn bối rối vì Thay đổi kích thước chậm liên quan đến kho dữ liệu và OLAP. Vì vậy, các loại Kích thước thay đổi chậm có thể được áp dụng cho cơ sở dữ liệu quy trình giao dịch kinh doanh chính của tôi (OLTP) không? Tôi tự hỏi nếu tôi trộn nhiều khái niệm lên, sẽ đánh giá rất cao một số hướng dẫn.


Tôi thực sự sẽ làm cả hai: lưu trữ giá bán trong order_line lưu trữ lịch sử giá sản phẩm. Bởi vì cả hai đều phục vụ các mục đích khác nhau. Lưu trữ các giá bán sẽ làm cho các truy vấn trên đơn đặt hàng nhiều dễ dàng hơn và nhanh hơn. Mặt khác, bạn có thể muốn lấy lại giá cũ ngay cả đối với các sản phẩm chưa được bán.
a_horse_with_no_name

Chắc chắn làm cho các truy vấn đơn hàng dễ dàng hơn không thể là trình điều khiển duy nhất đằng sau việc tiết kiệm giá cuối cùng mỗi lần. Đó là một cơ sở dữ liệu quan hệ sau tất cả - các truy vấn sẽ khó hơn nhiều.
Gaz_Edge

3
Lưu trữ giá bán trong dòng đơn hàng không phải là "không liên quan" (và tôi thực sự coi nó là bình thường hóa cũng như giá bán là một thuộc tính trực tiếp của dòng đơn hàng theo ý kiến ​​của tôi). Nghệ thuật sử dụng cơ sở dữ liệu quan hệ là về việc biết các giới hạn. Nếu bạn đang điều hành một cửa hàng với 100 sản phẩm và 5 đơn hàng mỗi ngày, thì việc lưu trữ và truy xuất giá cũ không phải là vấn đề. Nếu bạn đang điều hành một thị trường với hàng triệu sản phẩm, hàng ngàn đại lý và vô số đơn hàng mỗi phút, thì việc truy vấn lịch sử đó sẽ là một vấn đề.
a_horse_with_no_name

Bạn sẽ lưu trữ giá lịch sử ở đâu? Từ những gì tôi đang đọc, tôi cần hai cơ sở dữ liệu. Một cho OLTP một cho OLAP. Lịch sử đi vào OLAP?
Gaz_Edge

Câu trả lời:


10

Như bạn đã xác định, việc lưu trữ giá trên đơn đặt hàng giúp việc triển khai kỹ thuật dễ dàng hơn. Có một số lý do kinh doanh tại sao điều này có thể có lợi mặc dù.

Ngoài các giao dịch trên web, nhiều doanh nghiệp hỗ trợ bán hàng thông qua các kênh khác, ví dụ:

  • Qua điện thoại
  • Đại lý bán hàng "trên đường"
  • Tại một địa điểm (ví dụ: cửa hàng, văn phòng)

Trong những trường hợp này, lệnh có thể được nhập vào hệ thống tại một thời điểm sau khi giao dịch diễn ra. Trong những trường hợp này, khó có thể khó xác định chính xác bản ghi giá lịch sử nào nên được sử dụng - lưu trữ đơn giá trực tiếp trên đơn đặt hàng là lựa chọn khả thi duy nhất.

Nhiều kênh thường mang đến một thách thức khác - giá khác nhau cho cùng một sản phẩm. Phụ phí cho các đơn đặt hàng điện thoại là phổ biến - và một số khách hàng có thể tự thương lượng giảm giá. Bạn có thể biểu thị tất cả giá có thể cho tất cả các kênh trong lược đồ sản phẩm của mình, nhưng việc kết hợp giá này vào các bảng đơn hàng của bạn có thể trở nên (rất) phức tạp.

Bất cứ nơi nào đàm phán được cho phép, rất khó để liên kết lịch sử giá với giá đặt hàng đã thỏa thuận (trừ khi các đại lý có giới hạn đàm phán rất hẹp). Bạn cần lưu trữ giá trên đơn đặt hàng chính nó.

Ngay cả khi bạn chỉ hỗ trợ các giao dịch web và có cấu trúc giá tương đối đơn giản, vẫn có một vấn đề thú vị cần khắc phục - nên tăng giá như thế nào cho các giao dịch chuyến bay? Doanh nghiệp có khăng khăng rằng khách hàng phải trả tiền tăng hay họ tôn trọng giá gốc (khi sản phẩm được thêm vào giỏ hàng)? Nếu sau này thì việc triển khai kỹ thuật rất phức tạp - bạn cần tìm cách đảm bảo bạn duy trì phiên bản giá chính xác trong phiên.

Cuối cùng, nhiều doanh nghiệp đang bắt đầu sử dụng giá cả rất năng động. Có thể không có một mức giá cố định cho một sản phẩm nhất định - nó luôn được tính trong thời gian chạy dựa trên các yếu tố như thời gian trong ngày, nhu cầu cho sản phẩm, v.v. Trong những trường hợp này, giá có thể không được lưu trữ so với sản phẩm ở nơi đầu tiên!


3

Tôi sẽ thêm một số điểm thực tế mà tôi đã thấy.

  1. Sản phẩm là thoáng qua.

    Những gì họ có thể biểu thị ngày hôm nay, có thể không giống như những gì họ đã sử dụng để biểu thị một năm trở lại. Mã sku giống nhau (và do đó là Product_id), có thể đề cập đến biến thể / loại sản phẩm khác nhau ở các giai đoạn khác nhau.

    Không phải ai cũng hiểu tất cả các mối quan tâm trong tầm tay; do đó, người dùng có thể thay đổi các thuộc tính của sản phẩm ban đầu thay vì tạo một sản phẩm mới từ sự thiếu hiểu biết của chính mình. Rất nhiều lần, điều này có thể xảy ra do kế hoạch mà người dùng đang thực hiện (Này! Tôi chỉ có thể có 100 sku, vậy tại sao không tiếp tục thay đổi những cái cũ thay vì nâng cấp gói) Vì vậy, bạn thấy, trong rất nhiều xe đẩy , một sản phẩm sẽ không bao giờ biểu thị điều tương tự mãi mãi.

  2. Giá khác nhau dựa trên điều kiện đặt hàng và vận chuyển

    Như người dùng @Chris đã đề cập, các mức giá khác nhau có thể được áp dụng trong các tình huống khác nhau.

    Trong hầu hết các giỏ hàng, bạn sẽ tìm thấy ít nhất 3 lĩnh vực khác nhau được lưu trữ - đơn giá, số tiền chiết khấu và giá chiết khấu. Trong những cái cao cấp hơn, bạn sẽ tìm thấy thêm 2 đơn giá có thuế, giá chiết khấu có thuế. Bạn có thể tìm thấy một vài trường nữa để mô tả chi phí phương thức giao hàng và phí phương thức thanh toán bổ sung. Phần trăm thuế có thể thay đổi tùy thuộc vào tiểu bang, sản phẩm, quốc gia, phương thức vận chuyển, v.v. và các đầu chi phí khác cũng vậy. Tương tự, giảm giá có thể thay đổi tùy thuộc vào địa lý, chương trình khuyến mãi, thời gian bán hàng và như vậy. Do đó, chỉ có thông tin có thể được lấy ở cấp đơn hàng và thông tin kết hợp này không thể được tạo từ dữ liệu trong bảng sản phẩm.

  3. Tách biệt mối quan tâm

    Rất nhiều giỏ hàng được triển khai theo cách để các nhóm khác nhau có thể kiểm soát các phần dữ liệu khác nhau. Một số người quản lý hệ thống đặt hàng không cần phải luôn biết tất cả các sản phẩm trong kho là gì, giá ở thời điểm khác nhau là gì, các lựa chọn thay thế cho một sku nhất định, v.v. Giữ dữ liệu liên quan đến sản phẩm cùng với dữ liệu đặt hàng giúp đạt được sự phân tách mối quan tâm. Điều này cũng có thể đúng ở các giai đoạn phát triển, nếu các nhóm khác nhau quản lý các phần khác nhau của hệ thống.

  4. Khả năng mở rộng dễ dàng hơn trên nhiều hệ thống

    Rất nhiều lần, Hệ thống quản lý đơn hàng, Công cụ quy tắc, Công cụ danh mục, Hệ thống quản lý nội dung đều được xây dựng / duy trì như các hệ thống riêng biệt. Điều này giúp tối ưu hóa cho các điều kiện tải khác nhau và tạo ra trí thông minh chuyên biệt cho từng hệ thống. Một hệ thống, sau đó, không thể bị giữ để đòi tiền chuộc vì không có sẵn thông tin từ một hệ thống khác.

  5. Thời gian phát triển và chạy nhanh hơn

    Tôi đã sử dụng thuật ngữ "thời gian phát triển" ở đây, mặc dù sử dụng "thời gian gỡ lỗi" sẽ thích hợp hơn. Bất cứ khi nào có bất kỳ sự phát triển mới nào xảy ra, sẽ nhanh hơn nếu có sẵn dữ liệu mà không cần thêm độ phức tạp của chính nó, bởi vì sau đó, sẽ có các chu kỳ gỡ lỗi tương đối nhỏ hơn.

    Hãy tưởng tượng bạn được yêu cầu tạo các báo cáo theo yêu cầu để được giảm giá theo từng ngày trong một tháng nhất định nửa năm trước. Nếu bạn có giá gốc, giá chiết khấu trong 1-2 bảng cùng với đơn đặt hàng, chi tiết mặt hàng đặt hàng, điều này là khá nhiều về phía trước. Tuy nhiên, nếu bạn phải đi và lấy giá từ một bảng khác, và sau đó giảm giá áp dụng từ một bảng khác, sau đó tìm ra các chi tiết, cả thời gian phát triển và chạy sẽ cao hơn.

Một thiết kế tốt nên cố gắng tối ưu hóa càng nhiều cho tương lai, cũng như cho hiện tại.


2

Nó có thể sẽ tốn nhiều chi phí hơn trong việc lưu trữ, nhưng tôi thích lưu trữ tất cả các chi tiết có liên quan đến việc bán hàng với chính giao dịch đó, vì vậy nếu vì bất kỳ lý do gì, đường dẫn kiểm toán của chúng tôi bị phá vỡ, hoặc một quản trị viên ghi đè lên các két sắt, các chi tiết của bán như: tiền tệ được sử dụng, đơn giá, qty, thuế áp dụng và giá trị họ đã đến, vv đều có sẵn. Tôi thường lưu trữ dưới dạng XML để nó có thể linh hoạt từ bán sang bán.


EDIT: Để mở rộng những gì tôi đã nói ngắn gọn ở trên, trong phần bình luận tiếp theo của tôi bên dưới và những gì @a_horse_with_no_name đã nói ở trên, sự dư thừa trong dữ liệu giao dịch không chỉ quan trọng, mà còn cần thiết ở quy mô.

Tôi giả định rằng bạn đang xây dựng bằng OOP và do đó bạn có thể có một đối tượng giao dịch và một đối tượng sản phẩm bao gồm tất cả và / hoặc một đối tượng giá. Theo kinh nghiệm cá nhân của riêng tôi, tôi thích được tiết lộ trong lịch sử của mình, việc lưu trữ tương đối khó khăn.

Những gì chúng tôi đã làm là tạo ra một lịch sử đối tượng mà bạn có thể tạo điều kiện bằng cách sử dụng RDBMS hiện tại hoặc một số hương vị của kho lưu trữ giá trị khóa NOSQL (hoặc thậm chí tốt hơn là RDBMS cho phép NoQuery như các kết nối như handlersocket hoặc memcache) và chúng tôi lưu trữ lịch sử đối tượng theo cách đó, với mọi chi tiết và giá cả thay đổi ở một nơi dễ dàng và nhanh chóng có sẵn. Nếu bạn nghiêm túc, bạn thậm chí có thể sử dụng DIFF để lưu trữ và chỉ lưu trữ các thay đổi về phía trước, mặc dù nó có cảnh báo riêng. Điều đó sẽ quan tâm đến lịch sử của bạn và lợi thế của các đối tượng được tuần tự hóa là hệ thống của bạn sẽ / sẽ có thể đưa chúng trở lại như các đối tượng mà chúng được lưu trữ. Điều đó quan tâm đến lịch sử.

Đối với đề xuất của tôi, lưu trữ các chi tiết giao dịch như thuế, tiền tệ, v.v. với chính giao dịch đó có nghĩa là không cần phải tìm các chi tiết khác, đối tượng giao dịch của bạn sẽ nhận thức được các thuộc tính của nó và bạn có thể quan tâm đến việc trình bày dữ liệu khác nhau khi bạn thấy phù hợp. Bạn có thể truy cập nhanh vào ảnh chụp nhanh và có thêm lợi ích của các hồ sơ dự phòng và có thể kiểm chứng.

Thật đáng giá, tin tôi đi!


điều đó không thực sự có ý nghĩa để nói rằng bạn không sử dụng nó bởi vì nó có thể bị xóa. Bạn có thể ghi đè bất kỳ dữ liệu. Bất kỳ chiến lược nào cũng nên giữ bản sao lưu
Gaz_Edge

@Gaz_Edge Chúng không loại trừ lẫn nhau, bạn vẫn có thể sử dụng quy trình kiểm toán và lưu trữ các chi tiết với các giao dịch, sự dư thừa trong trường hợp này là hợp lý. Không bao giờ để lại cho mình dữ liệu chủ đề quan trọng này đến một điểm thất bại duy nhất. Trong trường hợp của chúng tôi, tôi sử dụng kho đối tượng tập trung làm cơ chế lịch sử thay vì cố gắng xây dựng lịch sử cho mỗi loại đối tượng (như giao dịch hoặc sản phẩm trong trường hợp này). Tôi sẽ có cả hai đối tượng giao dịch trong lịch sử nhưng tất cả các chi tiết quan trọng nhất với bản ghi. Đó hoàn toàn là một bên của các đối tượng sản phẩm trong lịch sử.
oucil

nếu tôi muốn chạy báo cáo về các đơn đặt hàng thì sao? Giống như có bao nhiêu sản phẩm x đã được mua? Hoặc có bao nhiêu đơn đặt hàng trên y số lượng? Lưu dưới dạng XML có nghĩa là bạn mất khả năng truy vấn dữ liệu, trừ khi tôi nhầm
Gaz_Edge

@Gaz_Edge Không đúng, nếu bạn đang nói về MySQL, bạn đã có SELECT ExtractValue(field_name, '/x/path/');để bạn có thể lọc các thứ như, tất cả các giao dịch bằng một loại tiền cụ thể hoặc tất cả các giao dịch có giá trị thuế tối thiểu nhất định hoặc bất cứ điều gì. Báo cáo quy mô lớn hơn có thể được thực hiện từ lịch sử đối tượng. Đối với các báo cáo quy mô lớn hơn, bạn có thể thiết lập một elasticsearchmáy chủ / phiên bản có báo cáo kiểu BigData và nó dễ dàng chia tỷ lệ thành nhiều triệu tài liệu +.
cilil

@Gaz_Edge Tôi cũng nên đề cập, các báo cáo bạn đang nói đến (mua trên giá trị, bán sản phẩm, v.v.) là các báo cáo phổ biến và các báo cáo nên được lưu trữ dưới dạng giá trị cột với bản ghi giao dịch để xử lý nhanh hơn. Bất cứ điều gì quan trọng nhưng không nhất thiết phải được báo cáo thường có thể đi vào XML. Dữ liệu ảnh chụp thực sự chỉ dành cho hai điều, 1. vấn đề Kích thước thay đổi chậm và 2. Xác thực và so sánh khi khách hàng phàn nàn và bạn cần nhanh chóng xem ai đúng. Nó không phải để sử dụng hàng ngày.
cilil

1

Phiếu bầu của tôi sẽ là lưu trữ đơn giá trên chi tiết đơn hàng của bạn và theo dõi lịch sử giá của các sản phẩm của bạn trong một bảng riêng biệt. Biện minh của tôi cho điều này là để thêm linh hoạt.

Ngay cả khi cấu trúc giá của bạn cứng nhắc và được xác định rõ ràng và không cho phép các biến thể mà @Chris Saxon đã đề cập ở trên, bạn có thoải mái rằng nó sẽ luôn như vậy không? Ngay cả khi bạn tự tin, tại sao lại vẽ mình trong một góc? Tôi nghĩ rằng sẽ là một ý tưởng tốt khi lưu trữ thông tin này trên chi tiết chi tiết đơn hàng vì tôi không thể nghĩ ra lý do thuyết phục để giữ riêng biệt.

Đối với việc lưu trữ lịch sử giá của bạn, có giá trị nhất định trong việc lưu trữ riêng biệt vì có thể có thay đổi về giá của một mặt hàng và không ai mua nó. Đó chắc chắn sẽ là thông tin hữu ích để biết nếu thay đổi giá là không hiệu quả. Như bạn đã đề cập, đây là trường hợp sử dụng cổ điển của Loại 2 Thay đổi kích thước chậm trong kịch bản kho dữ liệu. Thông thường, bất kỳ thay đổi giá nào trong bảng sản phẩm của bạn sẽ được ghi lại và một hàng mới sẽ được thêm vào bảng thứ nguyên với giá cập nhật và dấu thời gian để cho biết khi nào thay đổi này diễn ra. Hàng trước sẽ cập nhật ngày kết thúc để chỉ ra rằng đó không còn là giá hiệu quả. Vì vậy, một cách tiếp cận sẽ là theo dõi loại thay đổi này trong kho dữ liệu.

Tuy nhiên, nếu bạn không muốn quan tâm đến việc thiết kế lược đồ kho dữ liệu và quy trình ETL cùng lúc với thiết kế cơ sở dữ liệu thương mại điện tử OLTP của bạn, thì lịch sử này chắc chắn có thể được ghi lại trong cơ sở dữ liệu thương mại điện tử của chúng tôi. Điều này có thể được thực hiện như bạn đã mô tả với việc tạo một bảng sản phẩm_audit riêng biệt treo trên bảng sản phẩm và chứa ngày bắt đầu và ngày kết thúc khi phiên bản sản phẩm đó có hiệu lực. Nó cũng có thể được thực hiện trong bảng sản phẩm bằng cách thêm ngày bắt đầu và ngày kết thúc vào bảng để cho biết sản phẩm nào đang hoạt động. Tuy nhiên, tùy thuộc vào số lượng sản phẩm và số lượng hoặc thay đổi giá mà công ty bạn trải qua, điều này có thể làm cho bảng sản phẩm của bạn lớn hơn nhiều so với dự định và có thể gây ra các vấn đề về hiệu suất truy vấn sau này.

Cuối cùng, tách biệt lịch sử giá của bạn với đơn giá thực tế trên chi tiết đơn hàng chắc chắn có thể mang đến một số cơ hội phân tích khác để xem khi nào sản phẩm được bán ở mức giá cao hơn hoặc thấp hơn giá niêm yết tại thời điểm đó.


cảm ơn câu trả lời Tôi nghĩ rằng chiến lược tôi sẽ thực hiện là thiết kế OLTP cho mỗi cuốn sách. Tôi thực sự thích ý tưởng có một kho dữ liệu để báo cáo. Mặc dù nó bổ sung một số công việc bổ sung (tạo lược đồ mới), lược đồ có thể được điều chỉnh theo OLAP. Loại tránh một kịch bản trong đó tôi đang cố gắng lắp một cái chốt vuông vào một cái lỗ tròn.
Gaz_Edge

@Gaz_Edge: Đang trong tình huống tương tự về việc đưa ra quyết định cho dự án mới của tôi. Bạn có thể quan tâm để chia sẻ suy nghĩ của bạn về cách tiếp cận thiết kế mà bạn mất một năm trở lại? Nó có hoạt động tốt không?
tuyệt đối

@CoderAbsolute giải pháp ban đầu của tôi rất được định hướng 'cơ sở dữ liệu'. Ứng dụng của tôi hiện tập trung vào Kiến trúc hướng dịch vụ. Bây giờ tôi có nhiều lược đồ cơ sở dữ liệu tách rời nhỏ hơn là một lược đồ kết hợp chặt chẽ. Nhu cầu 3N trên một lược đồ lớn đã biến mất. Vì vậy, bây giờ tôi chỉ cần thêm đơn giá trực tiếp vào đơn đặt hàng. Giữ thay đổi giá sản phẩm lịch sử bây giờ đã biến mất vì nó không phải là một yêu cầu kinh doanh. Mong rằng sẽ giúp.
Gaz_Edge

0

Tôi hoàn toàn đồng ý với ý tưởng chính là giữ thông tin liên quan đến trật tự (bối cảnh) cùng nhau. Chỉ cần một lưu ý nhỏ rằng tình huống như vậy sẽ chỉ phát sinh khi bạn đang thiết kế ứng dụng của mình rất nhiều cơ sở dữ liệu tập trung và mọi thứ đều xoay quanh db béo lớn. Nếu bạn chuyển đổi quan điểm của mình bằng cách nhìn vào miền vấn đề từ một góc độ khác, bạn sẽ thấy rõ thứ tự đó là ảnh chụp nhanh của một sự kiện rất đặc biệt trong vòng đời của ứng dụng của bạn. Khi bạn xử lý các vấn đề dựa trên ngữ cảnh thì các vấn đề cơ sở dữ liệu sẽ trở thành vấn đề thứ yếu và phức tạp khiến mọi người sợ về việc truy vấn và thực hiện các báo cáo sẽ được xử lý liền mạch trong mô hình miền.


Một số ví dụ nhỏ sẽ làm cho câu trả lời của bạn dễ hiểu hơn nhiều. Đặc biệt là những câu như 'order là một ảnh chụp nhanh về một sự kiện rất đặc biệt trong vòng đời của ứng dụng của bạn'.
dezso
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.