Bagaimana cara menyimpan harga yang memiliki tanggal efektif?

21

Saya punya daftar produk. Masing-masing ditawarkan oleh penyedia N.

Setiap penyedia mengutip kami dengan harga untuk tanggal tertentu. Harga itu efektif hingga penyedia memutuskan untuk menetapkan harga baru. Dalam hal ini, penyedia akan memberikan harga baru dengan tanggal baru.

Header tabel MySQL saat ini terlihat seperti:

provider_id, product_id, price, date_price_effective

Setiap hari, kami menyusun daftar produk / harga yang efektif untuk hari ini. Untuk setiap produk, daftar tersebut berisi daftar penyedia yang diurutkan yang memiliki produk tertentu. Dengan begitu, kita dapat memesan produk tertentu dari siapa pun yang kebetulan menawarkan harga terbaik.

Untuk mendapatkan harga efektif, saya memiliki pernyataan SQL yang mengembalikan semua baris yang ada date_price_effective >= NOW(). Kumpulan hasil itu diproses dengan skrip ruby ​​yang melakukan penyortiran dan penyaringan yang diperlukan untuk mendapatkan file yang terlihat seperti ini:

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

Ini berfungsi dengan baik untuk tujuan kita, tetapi saya masih merasa gatal bahwa tabel SQL mungkin bukan cara terbaik untuk menyimpan informasi semacam ini. Saya merasa bahwa masalah semacam ini telah diselesaikan sebelumnya dengan cara yang lebih kreatif lainnya.

Apakah ada cara yang lebih baik untuk menyimpan informasi ini selain di SQL? atau, jika menggunakan SQL, apakah ada pendekatan yang lebih baik daripada yang saya gunakan?

edmz
sumber
lal00: ​​Seperti yang saya sebutkan di salah satu komentar saya, saya menangani kencan yang efektif secara teratur. Silakan lihat jawaban saya untuk metode penanganan tanggal yang efektif dan sederhana. Itu tidak mengharuskan seseorang untuk mengetahui periode bahwa harga efektif ketika baris harga baru dibuat, juga tidak mengharuskan seseorang untuk kembali memodifikasi baris terbaru saat ini saat baris baru dibuat.
bit-twiddler

Jawaban:

17

Untuk item yang bervariasi berdasarkan waktu (seperti dapat menjawab hal-hal seperti "berapa harga X pada tanggal D" atau "sapi mana yang ada di tempat pemberian pakan Q pada tanggal E") Saya sarankan membaca buku "Mengembangkan Berorientasi Waktu Aplikasi Basis Data dalam SQL. " Sementara buku ini tidak dicetak, penulis dengan ramah menyediakan PDF dari buku tersebut serta CD terkait di situs webnya.

http://www.cs.arizona.edu/~rts/publications.html (lihat item pertama di bawah "buku").

Untuk pengantar singkat daring, lihat:

Tangurena
sumber
1
Yah, ini bukan yang ada dalam pikiran saya ketika saya bertanya, lebih baik! :)
edmz
3

Saya pasti akan menyimpan tanggal efektif dalam database. Lagi pula, kemungkinan orang akan ingin dapat menjalankan kueri untuk melihat bagaimana harga telah berubah dari waktu ke waktu atau untuk mengecek keanehan dalam pesanan terhadap tabel harga produk historis. Bergantung pada jenis kueri yang Anda jalankan dan frekuensi perubahan harga, mungkin masuk akal untuk memiliki tabel terpisah untuk harga saat ini dan harga historis.

Di sebagian besar sistem yang menyimpan harga, Anda ingin kolom tanggal kedaluwarsa di samping tanggal efektif untuk membuatnya lebih mudah untuk menentukan harga yang sedang berlaku karena menghemat masalah Anda harus melihat pada baris sebelum atau berikutnya untuk mencari tahu keluar harga yang berlaku pada titik waktu tertentu. Saya tidak jelas tentang apa NOW() >= date_price_effectivekondisi Anda lakukan - mungkin, yang mengembalikan harga saat ini bersama dengan semua harga historis sebelumnya yang tampaknya aneh bagi saya. Saya akan berpikir bahwa "harga efektif" akan menjadi harga saat ini yang akan ditentukan oleh sesuatu sepertiNOW() BETWEEN date_price_effective AND date_price_expired

Saya juga tidak yakin seperti apa file Anda seharusnya. Tidak jelas bagi saya apa yang provider_1mewakili - harga provider_id = 1? - atau bagaimana Anda memesan data penyedia - mengapa provider_1muncul pertama untuk product_id_1dan ketiga untuk product_id_2.

Gua Justin
sumber
Justin, tanggal kedaluwarsa masuk akal. Anda benar, saya punya SQL sebaliknya. File output tidak terlalu relevan dengan pertanyaan saya, saya hanya menambahkan sebagai cara untuk memberi contoh bahwa saya perlu mengurutkan produk berdasarkan harga.
edmz
Seseorang tidak perlu memasukkan tanggal kedaluwarsa di setiap baris, karena hal itu hanya menambah biaya tambahan, karena orang biasanya tidak diberi periode harga efektif ketika baris dibuat. Jika kami memiliki N baris untuk setiap pasangan producer_id / product_id dalam sebuah tabel, yang masing-masing berlaku pada tanggal tertentu, baris dengan nilai date_price_effective terbesar yang kurang dari atau sama dengan tanggal yang ditentukan adalah harga yang berlaku pada tanggal itu. Jika Anda melihat postingan saya, Anda akan melihat kode SQL yang melakukan jenis query ini. Saya harus berurusan dengan tanggal yang efektif secara teratur.
bit-twiddler
@ bit-twiddler - Tentu saja, tidak perlu memiliki tanggal kedaluwarsa. Namun, memiliki tanggal kedaluwarsa umumnya membuat kueri tabel lebih mudah dan lebih efisien. Karena kueri tanggal yang efektif umumnya jauh lebih umum daripada perubahan harga, itu biasanya merupakan trade-off yang senang saya buat.
Justin Cave
3

Jika saya memahami pernyataan masalah Anda dengan benar, Anda perlu cara untuk menangani data generasional (yaitu, tabel berisi beberapa baris untuk setiap pasangan provider_id / product_id yang masing-masing merupakan sensistive tanggal). Dalam hal ini, Anda mencari harga terbaru untuk produk dengan nilai date_price_effective yang kurang dari atau sama dengan hari ini. Jenis situasi ini mudah ditangani menggunakan SQL subselect.

 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() 
     );

Harga berlaku selama memiliki nilai date_price_effective terbesar yang kurang dari atau sama dengan tanggal ketika kueri dieksekusi. Nilai date_price_effective yang lebih besar dari hari ini adalah tanggal efektif di masa mendatang. Kode yang tercantum di atas mengembalikan data baris untuk setiap pasangan provider_id / product_id yang memiliki nilai date_price_effective yang paling dekat dengan, tetapi tidak lebih lama dari tanggal kueri dieksekusi. Solusinya secara otomatis kurung harga ke dalam rentang tanggal yang efektif. Kunci utama untuk tabel ini adalah triple {provider_id, product_id, date_price_effective};

bit-twiddler
sumber