3 votes

Conception de base de données : Réflexion sur les prix de vente

Je dois créer une solution de base de données pour offrir des remises sur les produits.

Tables actuelles:

Produits
Colonnes: IDProduit, IDTypeProduit, DateSortie

PrixProduits
Colonnes: IDPrixProduit, IDTypePrixProduit (un produit peut avoir n prix), IDProduit, Prix

Nous voulons pouvoir accorder une remise par IDProduit et/ou IDTypeProduit et/ou IDTypePrixProduit et/ou DateSortie.

Exemples de ventes:

  1. Remise sur un seul IDProduit.
  2. Remise sur tous les produits d'un IDTypeProduit spécifié et IDTypePrixProduit spécifié.
  3. Remise sur tous les produits d'un IDTypeProduit spécifié avec une DateSortie du mois dernier.

L'aspect difficile du point #2 n'est pas l'exemple concret, mais la prise en compte de la scalabilité à long terme en cas d'ajout de nouveaux champs à l'avenir.

Je suis perplexe sur la façon de gérer le point #3 à cause de la DateSortie.

Voici ce que j'avais en tête avant de réaliser que j'avais besoin de venir sur Stackoverflow. Vous pouvez voir que la structure rigide ne permettra pas une bonne scalabilité en raison des colonnes explicitement incluses - si nous ajoutions de nouveaux critères à l'avenir, ces colonnes devraient être ajoutées à la table - sans même parler du fait qu'elle ne gère même pas la condition de DateSortie.

Nouvelle table:

RemisesPrixProduits
Colonnes: IDRemisePrixProduit, IDPrixProduit, IDTypeProduit, IDTypePrixProduit, Remise, TypeRemiseID (1 pour pourcentage, 2 pour fixe)

Ensuite, je pourrais utiliser quelque chose comme ceci pour obtenir les prix:

from p in Produits
join pp in PrixProduits on p.IDProduit equals pp.IDProduit
let rpp = (
    from rpp in RemisesPrixProduits
        .WhereIf(rpp.IDPrixProduit != null, rpp.IDPrixProduit == pp.IDPrixProduit)
        .WhereIf(rpp.IDTypeProduit != null, rpp.IDTypeProduit == p.IDTypeProduit )
        .WhereIf(rpp.IDTypePrixProduit != null, rpp.IDTypePrixProduit == pp.IDPrixProduit)
    select rpp).FirstOrDefault()
where p.IDProduit = IDProduit
select new 
{
    ...,
    Prix = pp.Prix,
    Remise = pp.Remise,
    PrixRemisé = 
        (rpp.TypeRemiseID == 1) ? 
            (pp.Prix - (pp.Prix * pp.Remise)) :
            (pp.Prix - pp.Remise) :
}

J'ai inclus cet exemple peu concluant que j'ai improvisé pour montrer le résultat final de la façon dont je dois pouvoir utiliser cette nouvelle fonctionnalité de remise sur les produits. Est-ce que quelqu'un peut offrir des conseils sur une bonne façon de gérer cette situation? Merci.

2voto

El Ronnoco Points 5941

Je dirais que vous avez besoin d'une table DiscountDetail distincte. Quelque chose comme

   DiscountDetailID INT NOT NULL
   DiscountTypeID INT NOT NULL --(FK Sur les types de remise - peut-être pas nécessaire)
   DiscountProductTypeID INT NULL --(FK SUR ProductType)
   DiscountProductID INT NULL --(FK SUR Product)
   DiscountAmount INT NULL --(Une valeur liée à la réduction en pourcentage peut-être?)
   DiscountDateStart DATETIME NOT NULL
   DiscountDateEnd DATETIME NULL

Avec quelques left join sympas et des calculs funky, vous devriez pouvoir obtenir une liste de tous les produits/types et les prix remisés à un moment donné...

1voto

GoatBreeder Points 871

J'ai fini par opter pour mon design original, et lorsque je interroge la base de données en utilisant Linq to SQL, j'obtiens le "DiscountedPrice" en utilisant une méthode. La méthode exécute sa propre requête et effectue une logique conditionnelle avant de retourner les résultats. Cela me donne donc la possibilité de faire effectuer à mon code un travail supplémentaire que ma requête ne pourrait pas effectuer. J'ai également créé une classe Enum pour les identifiants spéciaux ProductPriceDiscountIds afin qu'ils puissent être facilement identifiés. J'espère que cela aidera d'autres personnes qui se retrouvent dans une situation similaire - cela fonctionne très bien pour moi jusqu'à présent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X