J'ai une liste de produits. Chacun d'eux est proposé par N prestataires.
Chaque fournisseur nous propose un prix pour une date précise. Ce prix est effectif jusqu'à ce que le fournisseur décide de fixer un nouveau prix. Dans ce cas, le fournisseur donnera le nouveau prix avec une nouvelle date.
L'en-tête de table MySQL ressemble actuellement à:
provider_id, product_id, price, date_price_effective
Tous les deux jours, nous établissons une liste de produits / prix en vigueur pour la journée en cours. Pour chaque produit, la liste contient une liste triée des fournisseurs qui ont ce produit particulier. De cette façon, nous pouvons commander certains produits à quiconque vous propose le meilleur prix.
Pour obtenir les prix effectifs, j'ai une instruction SQL qui renvoie toutes les lignes qui en ont date_price_effective >= NOW()
. Cet ensemble de résultats est traité avec un script ruby qui effectue le tri et le filtrage nécessaires pour obtenir un fichier qui ressemble à ceci:
product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...
Cela fonctionne bien pour nos besoins, mais j'ai toujours la démangeaison qu'une table SQL n'est probablement pas la meilleure façon de stocker ce type d'informations. J'ai le sentiment que ce genre de problème a été résolu auparavant par d'autres moyens plus créatifs.
Existe-t-il un meilleur moyen de stocker ces informations autrement qu'en SQL? ou, si vous utilisez SQL, y a-t-il une meilleure approche que celle que j'utilise?
Réponses:
Pour les éléments qui varient en fonction du temps (comme être en mesure de répondre à des questions comme «quel était le prix de X à la date D» ou «quelle vache était dans le parc d'engraissement Q à la date E»), je recommande de lire le livre «Developing Time-Oriented Applications de base de données en SQL. " Bien que ce livre soit épuisé, l'auteur a gracieusement mis à disposition le PDF du livre ainsi que le CD associé sur son site Web.
http://www.cs.arizona.edu/~rts/publications.html (recherchez le premier élément sous "livres").
Pour une brève introduction en ligne, voir:
la source
Je conserverais certainement la date d'entrée en vigueur dans la base de données. Après tout, il est probable que les gens voudront pouvoir exécuter des requêtes pour voir comment le prix a changé au fil du temps ou pour recouper les bizarreries des commandes par rapport au tableau historique des prix des produits. Selon le type de requêtes que vous exécutez et la fréquence des changements de prix, il peut être judicieux d'avoir des tableaux séparés pour le prix actuel et les prix historiques.
Dans la plupart des systèmes qui stockent les prix, vous voudriez une colonne de date d'expiration en plus de la date effective pour faciliter la détermination du prix actuellement en vigueur car cela vous évite d'avoir à regarder la ligne précédente ou suivante pour figurer quel prix était en vigueur à un moment donné. Je ne sais pas exactement ce que fait votre
NOW() >= date_price_effective
état - sans doute, qui renvoie le prix actuel avec tous les prix historiques antérieurs, ce qui me semble étrange. Je pense que le "prix effectif" serait le prix actuel qui serait défini par quelque chose commeNOW() BETWEEN date_price_effective AND date_price_expired
Je ne sais pas non plus à quoi votre fichier est censé ressembler. Pour moi, ce que
provider_1
représente - le prix provider_id = 1? - ni comment vous commandez les données du fournisseur - pourquoiprovider_1
apparaît en premier pourproduct_id_1
et en troisième pourproduct_id_2
?la source
Si je comprends bien votre énoncé de problème, vous avez besoin d'un moyen de gérer les données générationnelles (c'est-à-dire que la table contient plusieurs lignes pour chaque paire provider_id / product_id dont chacune est sensible à la date). Dans ce cas, vous recherchez le prix le plus récent pour un produit dont la valeur date_price_effective est inférieure ou égale à aujourd'hui. Ce type de situation est facile à gérer à l'aide d'une sous-sélection SQL.
Un prix est effectif tant qu'il a la plus grande valeur date_price_effective inférieure ou égale à la date d'exécution de la requête. Une valeur date_price_effective supérieure à aujourd'hui est une date effective future. Le code répertorié ci-dessus renvoie les données de ligne pour chaque paire provider_id / product_id dont la valeur date_price_effective est la plus proche, mais pas plus tard que la date d'exécution de la requête. La solution place automatiquement les prix dans des plages de dates effectives. La clé primaire de cette table serait le triple {provider_id, product_id, date_price_effective};
la source