2012-03-24 4 views
1

J'ai rencontré quelques questions sur les mêmes lignes mais pas exactement la même chose.Calculs en php ou en données mysql

Lequel est le meilleur, effectuer quelques calculs de base en PHP après avoir obtenu des résultats de MySql (en joignant quelques tables) ou physiquement avoir une autre colonne dans MySql qui stocke le total tout en insérant une nouvelle ligne.

par exemple: un produit vendu:

Item   Price  Quantity  Discount 
Item 1  55   100   10% 

Ce qui précède est une table de vente, la colonne de prix est joint de la table des éléments. Sur la base de la question ci-dessus soit nous pouvons utiliser PHP pour récupérer les résultats, effectuer Price X Quantity X 0.10 ou nous notre table peut ressembler à ce qui suit:

Item   Price  Quantity  Discount Amount 
Item 1  55   100   10%  4950 

Maintenant, ce qui est la meilleure façon de faire une tâche simple?

Question similaire: Doing Calculations in MySql vs PHP

+0

[Faire des calculs dans MySQL vs PHP] (http://stackoverflow.com/questions/6449072/doing-calculations-in-mysql-vs-php) –

+0

@DanLee, c'est-à-dire effectuer des calculs dans MySql, le mien est stocké la valeur dans une autre colonne. – Namit

+0

Si vous ajoutez une autre colonne et que vous devez vous soucier de 2 tables lors de la mise à jour, je m'en tiendrai à la solution de jointure. Parce que cela peut devenir salissant –

Répondre

2

Il n'y a pas de règle générale pour toutes les situations. De nombreux facteurs affectent la performance et l'efficacité des sites Web. Il n'y a donc pas de "meilleur".

Si vous regardez quelque chose comme Magento, il le fait dans les deux sens. D'une part, il a une structure complète d'EAV avec chaque élément de données extrait et normalisé au nième degré. D'un autre côté, il agrège également les valeurs pré-calculées dans les tables plates pour des raisons de performances. Cela inclut les montants des escomptes, les prix de base, les quantités fiscales (en devise de base et choisie), etc. La première situation est la meilleure en termes de flexibilité et de robustesse, la table plate est meilleure en termes de performance.

Une table plate accélère évidemment les calculs de masse, car tout a déjà été élaboré. Mais comme le souligne kernelpanic, cela signifie que toute modification des paramètres peut nécessiter un recalcul de toutes les valeurs. Dans le cas de données historiques telles que l'historique des commandes, vous ne voudrez probablement pas recalculer les montants réels payés par les utilisateurs, mais la possibilité d'avoir à le faire doit être prise en considération lors de la détermination de la meilleure solution.

Si les performances sont primordiales et que les calculs sont coûteux à exécuter, sachant que vous devrez peut-être actualiser les valeurs en masse de temps en temps, vous pourrez prendre une décision éclairée de les mettre en cache ou non.Mais si ce n'est pas un aspect critique des performances ou si les calculs sont coûteux mais ne sont pas exécutés souvent, il est préférable de les laisser hors de la base de données.

Encore une fois il y a plus d'une façon de définir «meilleur», donc cela dépend des circonstances. Il s'agit simplement d'équilibrer les exigences - rapidité, propreté, utilisation de la mémoire, besoins du processeur, utilisation de l'espace disque, nécessité de s'adapter à une structure de données arbitraire définie par les responsables du développement - votre décision devra tenir compte de ces facteurs.

Sans un problème du monde réel à traiter, la spéculation est vraiment tout ce qui peut être donné. Si vous avez une situation plus complexe, je serais heureux de jeter un coup d'oeil et offrir mes pensées.

edit: D'après mes propres observations, une page de catalogue Magento avec des données à plat et plus de 200k produits se charge en 10 à 20 secondes sans mise en cache de page activée. Lorsque les données à plat étaient désactivées et que la structure EAV était utilisée, cela prenait quelques minutes. Je ne suis pas au travail en ce moment, donc je n'ai pas mes données de profilage à portée de main, mais c'est un témoignage du fait que dans les applications du monde réel, il n'y a pas de meilleure solution.

0

Je garderais les prix pré-calculés sur la table. De cette façon, si votre remise change pour dire 15%, vous n'aurez pas à recalculer la valeur pour chaque ligne à chaque fois.

0

je vais préfère la structure de la table supérieure, nous pouvons gérer toutes ces choses par notre calcul, nous ne devons pas garder ces calculs dans DB parce que nous devons suivre le SGBDR approche

1

Il suffit d'ajouter les calculs à votre instruction SELECT.

Exemple:

SELECT 
    ItemID, 
    Price, 
    Quantity, 
    Discount 
    Price * Quantity * Discount AS Amount 
FROM myTable 

Ou utiliser des vues pour récupérer les données que vous souhaitez et ajoutez les valeurs calculées sous forme de colonnes. De cette façon, les valeurs calculées ne sont valables que pour la requête et vous n'avez pas besoin d'ajouter des colonnes supplémentaires aux tables.

2

Les calculs peuvent être effectués soit par une requête SQL lors de l'extraction, soit après avoir extrait les données. La solution SQL serait quelque chose comme

SELECT *, ((Price * Quantity) - ((Price * Quantity) * (Discount * .01))) AS Amount 
FROM ... 

À bien des égards est juste une préférence personnelle, bien que lorsque SQL commence à devenir très compliqué, je trouve désordre de travailler avec. La chose que vous voulez probablement éviter est d'enregistrer le total dans la base de données, à moins que ce soit un montant fixe qui ne changera jamais. Si votre total est enregistré et que vous modifiez le montant ou la quantité de votre remise, vous risquez d'oublier de mettre à jour le total. Si chaque fois que vous avez besoin du total, vous le calculez à partir des variables connues (quantity * price - discount) alors le total devrait toujours être précis.