Làm thế nào để lưu trữ giá có ngày hiệu quả?


21

Tôi có một danh sách các sản phẩm. Mỗi người trong số họ được cung cấp bởi N nhà cung cấp.

Mỗi nhà cung cấp báo giá cho chúng tôi một ngày cụ thể. Giá đó có hiệu lực cho đến khi nhà cung cấp đó quyết định đặt giá mới. Trong trường hợp đó, nhà cung cấp sẽ đưa ra mức giá mới với một ngày mới.

Tiêu đề bảng MySQL hiện trông giống như:

provider_id, product_id, price, date_price_effective

Mỗi ngày, chúng tôi lập một danh sách các sản phẩm / giá có hiệu lực cho ngày hiện tại. Đối với mỗi sản phẩm, danh sách chứa danh sách được sắp xếp của các nhà cung cấp có sản phẩm cụ thể đó. Bằng cách đó, chúng tôi có thể đặt hàng một số sản phẩm từ bất cứ ai xảy ra để cung cấp giá tốt nhất.

Để có được giá hiệu quả, tôi có một câu lệnh SQL trả về tất cả các hàng có date_price_effective >= NOW(). Tập kết quả đó được xử lý bằng tập lệnh ruby ​​thực hiện sắp xếp và lọc cần thiết để có được một tệp trông như thế này:

product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...

Điều này hoạt động tốt cho mục đích của chúng tôi, nhưng tôi vẫn có một ý kiến ​​rằng bảng SQL có lẽ không phải là cách tốt nhất để lưu trữ loại thông tin này. Tôi có cảm giác rằng loại vấn đề này đã được giải quyết trước đây theo những cách sáng tạo khác.

Có cách nào tốt hơn để lưu trữ thông tin này ngoài SQL không? hoặc, nếu sử dụng SQL, có cách tiếp cận nào tốt hơn cách tôi đang sử dụng không?


lal00: ​​Như tôi đã đề cập trong một trong những bình luận của mình, tôi xử lý việc hẹn hò hiệu quả một cách thường xuyên. Xin vui lòng xem câu trả lời của tôi cho một phương pháp xử lý ngày hiệu quả đơn giản. Nó không yêu cầu người ta phải biết khoảng thời gian mà giá có hiệu lực khi một hàng giá mới được tạo, cũng không yêu cầu một hàng phải quay lại sửa đổi hàng mới nhất trước đó khi một hàng mới được tạo.
bit-twiddler

Câu trả lời:


17

Đối với các mặt hàng thay đổi theo thời gian (chẳng hạn như có thể trả lời những câu như "giá của X vào ngày D" hoặc "con bò nào trong thức ăn chăn nuôi Q vào ngày E") tôi khuyên bạn nên đọc cuốn sách "Phát triển theo định hướng thời gian Ứng dụng cơ sở dữ liệu trong SQL. " Trong khi cuốn sách này không còn xuất bản, tác giả đã sẵn sàng cung cấp bản PDF của cuốn sách cũng như đĩa CD liên quan trên trang web của mình.

http://www.cs.arizona.edu/~rts/publications.html (tìm mục đầu tiên trong "sách").

Đối với một giới thiệu ngắn gọn trực tuyến, xem:


1
Chà, đây không phải là điều tôi nghĩ khi tôi hỏi, nó tốt hơn! :)
edmz

3

Tôi chắc chắn sẽ lưu trữ ngày hiệu lực trong cơ sở dữ liệu. Rốt cuộc, có khả năng mọi người sẽ muốn có thể chạy truy vấn để xem giá đã thay đổi theo thời gian như thế nào hoặc kiểm tra chéo các đơn hàng trong bảng so với bảng giá sản phẩm lịch sử. Tùy thuộc vào loại truy vấn bạn đang chạy và tần suất thay đổi giá, có thể có các bảng riêng biệt cho giá hiện tại và giá lịch sử.

Trong hầu hết các hệ thống lưu trữ giá, bạn sẽ muốn có cột ngày hết hạn ngoài ngày có hiệu lực để dễ xác định giá nào hiện đang có hiệu lực vì nó giúp bạn tránh được vấn đề phải xem hàng trước hoặc hàng tiếp theo. giá nào có hiệu lực tại một thời điểm nhất định. Tôi không rõ NOW() >= date_price_effectiveđiều kiện của bạn đang làm gì - có lẽ, điều đó trả về giá hiện tại cùng với tất cả giá trước đây có vẻ kỳ lạ đối với tôi. Tôi nghĩ rằng "giá hiệu quả" sẽ là giá hiện tại sẽ được xác định bởi một cái gì đó nhưNOW() BETWEEN date_price_effective AND date_price_expired

Tôi cũng không chắc tập tin của bạn sẽ trông như thế nào. Tôi không rõ điều gì provider_1đại diện cho-- nhà cung cấp_id = 1 giá? - hoặc cách bạn đặt hàng dữ liệu của nhà cung cấp - tại sao lại provider_1xuất hiện đầu tiên cho product_id_1và thứ ba cho product_id_2.


Justin, ngày hết hạn có ý nghĩa. Bạn đã đúng, tôi đã có SQL theo cách khác. Tệp đầu ra không liên quan lắm đến câu hỏi của tôi, tôi chỉ thêm vào như một cách để minh họa rằng tôi cần sắp xếp các sản phẩm theo giá.
edmz

Người ta không cần bao gồm ngày hết hạn trong mỗi hàng, vì làm như vậy chỉ thêm chi phí bổ sung, vì người ta thường không đưa ra khoảng thời gian giá có hiệu lực khi hàng được tạo. Nếu chúng ta có N hàng cho mỗi cặp Produc_id / product_id trong một bảng, thì mỗi hàng có hiệu lực vào một ngày nhất định, hàng có giá trị date_price_effective lớn nhất nhỏ hơn hoặc bằng một ngày nhất định là giá có hiệu lực vào ngày đó. Nếu bạn nhìn vào bài đăng của tôi, bạn sẽ thấy mã SQL thực hiện loại truy vấn này. Tôi phải đối phó với ngày hiệu quả một cách thường xuyên.
bit-twiddler

@ bit-twiddler - Chắc chắn, không cần thiết phải có ngày hết hạn. Tuy nhiên, việc có ngày hết hạn thường làm cho việc truy vấn bảng dễ dàng và hiệu quả hơn nhiều. Vì các truy vấn ngày hiệu quả thường phổ biến hơn nhiều so với thay đổi giá cả, đó thường là một sự đánh đổi mà tôi rất vui khi thực hiện.
Hang Justin

3

Nếu tôi hiểu chính xác tuyên bố vấn đề của bạn, bạn cần một cách để xử lý dữ liệu thế hệ (nghĩa là bảng chứa nhiều hàng cho mỗi cặp nhà cung cấp_id / sản phẩm_id mỗi cặp có độ nhạy theo ngày). Trong trường hợp đó, bạn đang tìm kiếm mức giá gần đây nhất cho một sản phẩm có giá trị date_price_effective nhỏ hơn hoặc bằng ngày hôm nay. Loại tình huống này được xử lý dễ dàng bằng cách sử dụng một phụ chọn SQL.

 SELECT 
   provider_id, product_id, price, date_price_effective 
 FROM 
   price_table a 
 WHERE 
   date_price_effective = 
     (
       SELECT 
         MAX(date_price_effective) 
       FROM 
         price_table b 
       WHERE 
         b.provider_id = a.provider_id AND 
         b.product_id = a.product_id AND
         b.date_price_effective <= NOW() 
     );

Giá có hiệu lực miễn là nó có giá trị date_price_effective lớn nhất nhỏ hơn hoặc bằng ngày mà truy vấn được thực hiện. Giá trị date_price_effective lớn hơn ngày hôm nay là một ngày có hiệu lực trong tương lai. Mã được liệt kê ở trên trả về dữ liệu hàng cho từng cặp Carrier_id / product_id có giá trị date_price_effective gần nhất, nhưng không muộn hơn ngày truy vấn được thực thi. Giải pháp tự động đánh dấu giá vào phạm vi ngày có hiệu lực. Khóa chính cho bảng này sẽ là bộ ba {Carrier_id, product_id, date_price_effective};

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.