2010-04-07 7 views
1

J'ai une base de données qui contient un historique des ventes de produits. Par exemple, le tableau suivantBase de données de conception Question concernant les informations en double

CREATE TABLE SalesHistoryTable (
OrderID, // Order Number Unique to all orders 
ProductID, // Product ID can be used as a Key to look up product info in another table 
Price, // Price of the product per unit at the time of the order 
Quantity, // quantity of the product for the order 
Total, // total cost of the order for the product. (Price * Quantity) 
Date, // Date of the order 
StoreID, // The store that created the Order 
PRIMARY KEY(OrderID)); 

La table aura éventuellement des millions de transactions. À partir de là, des profils peuvent être créés pour des produits dans différentes régions géographiques (en fonction du StoreID). La création de ces profils peut prendre beaucoup de temps en tant que requête de base de données. Par exemple.

SELECT ProductID, StoreID, 
SUM(Total) AS Total, 
SUM(Quantity) QTY, 
SUM(Total)/SUM(Quantity) AS AvgPrice 
FROM SalesHistoryTable 
GROUP BY ProductID, StoreID; 

La requête ci-dessus pourrait être utilisée pour obtenir les informations basées sur des produits pour un magasin particulier. Vous pouvez ensuite déterminer quel magasin a le plus vendu, a fait le plus d'argent, et vend en moyenne pour le plus/le moins. Ce serait très coûteux à utiliser comme une requête normale exécutée à tout moment. Quelles sont les descisions de conception afin de permettre à ces types de requêtes de s'exécuter plus rapidement en supposant que la taille de stockage ne pose pas de problème. Par exemple, je pourrais créer une autre table avec des informations en double. ID de magasin (clé), ID de produit, TotalCost, QTY, AvgPrice Et fournir un déclencheur de sorte que lors de la réception d'une nouvelle commande, l'entrée pour ce magasin est mise à jour dans une nouvelle table. Le coût de la mise à jour est presque rien. Qu'est-ce qui devrait être pris en compte dans le scénario ci-dessus?

+1

Votre propre réponse est spot-on pour ce genre de requête. La mise en cache des résultats dans la base de données fournira une accélération beaucoup plus importante que tout ce que vous pouvez faire. L'autre bonne chose à propos de cette approche est que si les choses ne sont plus synchronisées pour une raison ou une autre, vous pouvez tout jeter et recréer la table avec une seule requête. – roufamatic

Répondre

2

Normalement, vous utiliseriez un entrepôt de données, mais à part cela, l'utilisation d'un déclencheur pour mettre à jour une deuxième table est une option parfaitement viable.

Vous pouvez également avoir une deuxième table qui est remplie par un travail par lots sur une base périodique (une option de type entrepôt de données plus). Vous pouvez également utiliser une vue matérialisée si votre base de données les prend en charge.

+0

+1: Merci, je vais regarder dans les vues matérialisées. – galford13x

1

Je considère:

  • un entrepôt de données/solution OLAP
  • (comme vous le dites) exécuter vos requêtes d'extraction de données sur une table précalculée séparée/jeu de données
  • indexées/vues matérialisées qui est presque le même que le point précédent

Il y a quelques questions cependant:

  • attendez-vous des données en temps réel?
  • quel est votre volume d'écriture?
  • quel moteur DB?
+0

+1: Les données peuvent être en temps réel avec les retards de latence hérités bien sûr. Je suppose que de mettre en lots des travaux et de faire la mise à jour des données 1/heure ou somesuch pourrait être une option aussi bien que Eric l'avait mentionné. Le volume d'écriture serait de l'ordre de> 1000/jour. Cependant, j'ai accès à des données qui remontent à 2006. Je ne suis pas encore sûr puisque je n'ai pas créé et importé les données, mais je suppose qu'il y a plus de 1,5 million de lignes d'information. – galford13x

1

Vous voudrez peut-être envisager d'utiliser materialized views, qui ne sera interrogée que périodiquement.

+0

+1: Merci, je n'ai pas entendu parler de vues matérialisées. Je vais certainement les examiner. – galford13x

0

"Le coût de la mise à jour est presque rien."

Sauf que toutes les mises à jour doivent maintenant être sérialisées. Car quoi qu'il en soit, l'ancienne loi de la physique reste que deux choses ne peuvent pas être au même endroit en même temps.

+0

Je pense que je vois ce que vous dites, mais je ne suis pas sûr de savoir comment cela s'applique. S'il y a 1000 ventes par heure, cela signifie 1000 insertions dans le SalesHistoryTable et 1000 déclencheurs qui provoquent 2 additions et une division + une mise à jour de ligne. Cela semble être beaucoup moins cher que d'exécuter la requête 1000 fois non? – galford13x

+0

Peut-être que je devrais changer ma déclaration à, "Le coût de la mise à jour est presque rien par rapport à la requête"? Cela pourrait être un peu plus relatif. – galford13x

Questions connexes