2010-02-24 3 views
8

Quelle manière est préférable de stocker des informations de vente dans une base de données:Quand faire des calculs

  1. coût de magasin pour un article et Prix de vente par article
  2. frais Magasin * qté et prix de vente * qty - donc vous stockez les totaux dans le db
+3

"Mieux"? Que signifie "mieux" dans ce contexte? Il y a des compromis spécifiques. Qu'est-ce qui est le plus important pour toi? –

Répondre

0

Je dirais que vous stockez toujours le coût et le prix comme des colonnes séparées ET stockez le total. Il y aura un moment où vous aurez besoin de ceux qui ont éclaté (reporting, facturation) que vous regretterez.

La question deviendra vraiment si vous stockez également les valeurs calculées. cela dépendra vraiment des circonstances de l'application (combien de lignes, combien de transactions, etc.). Si c'est une application de petite à moyenne taille, cela n'aura probablement aucune importance pour la performance, donc c'est juste une question d'autres facteurs.

Si la formule pour le total peut devenir plus compliquée (ex: taxes, réductions, etc.), vous pouvez stocker le total. sinon, devoir reproduire cette logique dans d'autres domaines peut s'avérer extrêmement difficile.

Personnellement, je stocke toujours le montant total également. Je trouve simplement que le coût de la colonne de base de données supplémentaire est toujours plus important que d'avoir ce total dans d'autres endroits.

+0

Dans la continuité de votre idée, @Cody C, sans oublier que les valeurs calculées stockées peuvent améliorer les performances lors du chargement et/ou de la création de rapports le moment venu. En fait, il est plus facile de faire des rapports avec des champs calculés stockés. Cela dépend toujours du type de calculs que vous devez effectuer. –

+0

On pourrait également souhaiter que ces champs calculés soient accessibles par le biais de propriétés en lecture seule où seul le getter est requis, car le logiciel devrait y insérer des valeurs, puisqu'elles sont calculées. Ces setters ne seraient utilisés que par la couche de persistance. –

0

J'irais avec stocker le coût d'un article et le prix de vente par article. Si vous n'enregistrez que les totaux, vous aurez du mal à recalculer vos valeurs si les prix changent. Imaginez donner un rabais saisonnier sur certains de vos articles, appliquer des taxes différentes à certains articles (peut-être même différents selon le pays d'origine du client) ou accorder des prix plus bas aux clients enregistrés - vous devrez calculer ces prix en fonction des ventes prix d'un article, les totaux ne sont d'aucune utilité dans ce cas.

Et si vous avez vraiment besoin des totaux, vous pouvez facilement les calculer tout moment en utilisant DB-requêtes simples, en prenant en compte toutes les remises, etc., etc.

0

à mon humble avis le coût du magasin et les ventes par article. Si vous souhaitez que les résultats soient similaires aux totaux, exécutez-les dans la requête ou créez une table temporaire ou une procédure stockée avec les calculs. Cependant, j'effectue habituellement ces calculs dans le code (PHP ou JAVA dans mon cas). Si c'est seulement à des fins de rapport, il est parfois bon de stocker les totaux comme une accélération des calculs (et empêche certains calculs de manque dans votre code).

6

Ceci est le problème 3rd Normal Form.

L'option 1 est dans la 3ème forme normale. Il n'y a pas de données dérivées. Le calcul doit être fait pour chaque requête. Pour cette raison, les mises à jour peuvent être effectuées sur n'importe quel champ sans rien casser.

L'option 2 rompt la 3e forme normale. Il enregistre les données dérivées. Les calculs ne sont pas effectués au moment de la requête, ce qui les rend beaucoup plus rapides. Cependant, une mise à jour qui ne refait pas également le calcul conduira à des données incohérentes. C'est ce qu'on appelle une "anomalie de mise à jour". Une mise à jour entraîne l'incohérence du champ de données dérivé. En outre, en fonction du calcul, il peut être impossible de déterminer les champs qui doivent changer lorsque les données dérivées doivent être modifiées.

+0

Oh mais si vous l'avez conçu correctement, une mise à jour corrigera les données agrégées. En fait, vous ne devriez pas faire cela, sauf si vous vous assurez que les mises à jour. – HLGEM

+0

@HLGEM: "l'a conçu correctement"? Qu'est-ce que ça veut dire? Avec un déclencheur ou quelque chose? –

+0

Dépend de ce que vous faites, cela peut signifier avec un déclencheur ou cela peut signifier avec un champ évalué – HLGEM

7

Stockez tous les détails pour chaque article, comme vous en aurez généralement besoin plus tard (à des fins statistiques/d'information ou pour toute autre raison).Vous devez vous assurer que vous suivez toujours la même logique de calcul pour obtenir le prix de vente total. Ainsi, vous devrez peut-être stocker des devises, des réductions, des unités de prix, etc. Voici quelques autres points à prendre en compte:

  • Si vous voulez sortir ultérieurement le prix d'un seul article, vous avez besoin des données d'article unique. Ne pas enregistrer le prix total avec les données d'un seul article, car vous devrez toujours garder les deux synchronisés. Vous serez intrigué quelques mois/années plus tard, sur lequel des deux à utiliser pour vos calculs.

  • Agréger vos données si vous les utilisez dans un entrepôt de données et n'avez pas besoin des détails.

0

Je ne conserverons les totaux si j'ai un grave problème de rapports où de nombreuses requêtes exigent la valeur totale d'un grand ensemble d'enregistrements (si vous obtenez seulement le total pour un petit ensemble, calcuating il onthe mouche lorsque demandé est OK).

Si vous stockez les totaux, vous avez besoin de déclencheurs pour vous assurer que les mises à jour, les suppressions et les insertions mettent correctement à jour les totaux. Sinon, les données seront désynchronisées et inutiles.

0

Cela dépend de ce que vous allez faire avec les données. Pour de nombreuses raisons, il est utile de stocker sous chaque article le prix unitaire de cet article, la quantité achetée et le prix calculé. Le prix calculé est la quantité multipliée par le prix unitaire. Est-ce redondant? Hé bien oui. Est-ce que cela viole une forme normale? Hé bien oui. Mais ça marche plutôt bien. Pourquoi enregistrer le prix dans la ligne d'article (enregistrement) et ne pas simplement compter sur les mêmes données de prix stockées dans la table de produit maître? Car si vous modifiez le prix après cette vente, vous ne souhaitez pas modifier le prix que ce client a dû payer pour cet achat. Pourquoi stocker le prix étendu, puisque cela peut être recalculé à la volée? Parce qu'il simplifie l'agrégation (somme ou moyenne) sur certains ensembles d'éléments plus tard.

Si vous stockez le prix étendu, vous pouvez utiliser les outils d'analyse point-clic (voir OLAP) pour une analyse ultérieure, sans autre programmation. Si vous comptez recalculer le prix étendu lorsque vous en avez besoin, vous pouvez constater que l'outil de zoom avant n'est pas assez intelligent pour effectuer la multiplication pour vous.

"articles" seront normalement enfants d'une plus grande unité de travail. Dans un système de facturation, un article fait partie d'une facture. Dans un système de comptabilité générale, un article fait partie d'une transaction. Les éléments ne sont pas équilibrés, mais la transaction est. Dans un grand nombre de systèmes de commerce, la fonction de facturation et la fonction de comptabilité sont issues de la même base de données, mais cela dépasse votre question.

Normalement, j'essaie de garder mes données normalisées. C'est un endroit où de nombreux experts s'écartent intentionnellement des exigences de la normalisation pure.