2008-11-17 10 views
21

Mon exemple simplifié et artificiel est le suivant: -Quelle est la meilleure façon de stocker des données d'historique dans SQL Server 2005/2008?

Disons que je veux mesurer et stocker la température (et d'autres valeurs) de toutes les villes du monde sur une base quotidienne. Je suis à la recherche d'un moyen optimal de stocker les données de sorte qu'il soit aussi facile d'obtenir la température actuelle dans toutes les villes, que d'avoir historiquement la totalité de la température dans une ville.

C'est un problème assez facile à résoudre, mais je cherche la meilleure solution.

Les 2 principales options que je peux penser sont les suivantes: -

Option 1 - magasins même table les enregistrements actuels et historiques

tous les magasins en cours et enregistre archives dans la même table.

à savoir

CREATE TABLE [dbo].[WeatherMeasurement](
    MeasurementID [int] Identity(1,1) NOT Null, 
    TownID [int] Not Null, 
    Temp [int] NOT Null, 
    Date [datetime] NOT Null, 
) 

Cela garderait tout simple, mais quelle serait la question la plus efficace pour obtenir une liste des villes et il y a la température actuelle? Est-ce que cette échelle une fois que la table a des millions de lignes? Y at-il quelque chose à gagner en ayant une sorte de drapeau IsCurrent dans la table?

Option 2 - Conservez tous les documents d'archives dans une table séparée

Il y aurait une table pour stocker les mesures en direct actuelles dans

CREATE TABLE [dbo].[WeatherMeasurement](
    MeasurementID [int] Identity(1,1) NOT Null, 
    TownID [int] Not Null, 
    Temp [int] NOT Null, 
    Date [datetime] NOT Null, 
) 

Et une table pour stocker Date d'archivage historique (inséré par un peut-être déclencher)

CREATE TABLE [dbo].[WeatherMeasurementHistory](
    MeasurementID [int] Identity(1,1) NOT Null, 
    TownID [int] Not Null, 
    Temp [int] NOT Null, 
    Date [datetime] NOT Null, 
) 

Cela a les avantages de maintenir les principales données actuelles maigre et très efficace pour interroger, au détriment de rendre le schéma plus complexes et en insérant des données plus coûteuses.

Quelle est la meilleure option? Y a-t-il de meilleures options que je n'ai pas mentionnées? REMARQUE: J'ai simplifié le schéma pour mieux cibler ma question, mais supposons qu'il y aura beaucoup de données insérées chaque jour (100 000 enregistrements) et que les données sont à jour pendant une journée. Les données actuelles sont tout aussi susceptibles d'être interrogées que l'historique.

+1

Prenez vos deux options et répondez-y afin que nous puissions voter –

Répondre

12

DEPENDS des modèles d'utilisation des applications ... Si les modèles d'utilisation indiquent que les données historiques seront interrogées plus souvent que les valeurs actuelles, placez-les toutes dans une table ... Mais si les requêtes historiques sont l'exception, (ou moins de 10% des requêtes), et la performance de la requête courante de valeur courante souffrira de mettre toutes les données dans une table, alors il est logique de séparer ces données dans sa propre table ...

0

Je suggère de garder dans le même tableau puisque les données historiques sont interrogées tout aussi souvent. Sauf si vous ajouterez beaucoup plus de colonnes à la table.

Lorsque la taille devient un problème, vous pouvez le partitionner par décennie et avoir une procédure stockée unir les lignes demandées.

+0

Avez-vous des opinions sur ce qui serait la requête la plus efficace pour obtenir une liste des villes et leur température actuelle. –

1

Une autre alternative pourrait être d'utiliser une table pour toutes les données et d'avoir une vue de la température actuelle. Cela n'aidera pas les performances, mais pourrait aider à la lisibilité/maintenabilité.Vous pouvez même opter pour une vue indexée pour améliorer les performances si vous disposez de la version appropriée de sql.

5

Je voudrais garder les données dans un tableau sauf si vous avez un biais très sérieux pour les données actuelles (en cours d'utilisation) ou les données d'historique (en volume). Un index composé avec DATE + TOWNID (dans cet ordre) supprimerait le problème de performance dans la plupart des cas (bien que nous n'ayons pas les données pour être sûrs de cela pour l'instant). La seule chose à laquelle je m'interrogerais est de savoir si quelqu'un voudra des données à la fois des données actuelles et historiques pour une ville. Si oui, vous venez de créer au moins une nouvelle vue à s'inquiéter et un problème de performance possible dans cette direction.

Ceci est malheureusement l'une de ces choses où vous devrez peut-être profiler vos solutions par rapport aux données du monde réel. Personnellement, j'ai utilisé des index composés tels que spécifiés ci-dessus dans de nombreux cas, et pourtant il y a quelques cas où j'ai choisi de diviser l'historique en une autre table. Eh bien, en fait un autre fichier de données, parce que le problème était que l'histoire était donc dense que j'ai créé un nouveau fichier de données pour lui seul pour éviter de gonfler l'ensemble du fichier de données primaires entières. Les problèmes de performance sont rarement résolus par la théorie.

Je vous recommande d'en savoir plus sur les conseils de requête pour l'utilisation d'index et sur les «index de couverture» pour plus d'informations sur les problèmes de performance.

+2

Je modifierais légèrement votre déclaration à "Les problèmes de performance sont rarement résolus en théorie * seuls *." Connaître la théorie est la seule façon d'avoir de bonnes intuitions à essayer tout en optimisant - sinon, vous êtes en train de vous débattre et d'améliorer la performance. Je suppose que c'est ce que vous vouliez dire. :) –

+0

Une indexation correcte devrait éliminer tout besoin de conseils de requête. Les conseils de requête ont tendance à bloquer l'optimiseur. Dans les 12 années de développement et de conception de SQL Server, je pense que j'ai dû utiliser un indice de requête une fois - peut-être deux fois. Le problème est, si vos données changent, SQL Server ne peut pas s'adapter une fois que vous avez l'indice de requête. –

+1

Je suis d'accord avec Ian et Tom. Vous devez comprendre la théorie, mais l'optimisation est toujours la main sur à la fin. En ce qui concerne les indices de requête, je suis d'accord qu'ils * ne devraient pas être nécessaires, mais si vous avez une impasse avec l'optimiseur intégré (2005 échoue où 2000 réussit parfois), vous utilisez un indice. – Godeke

0

Je voudrais utiliser une seule table avec des vues d'index pour me fournir les dernières informations. Les serveurs SQL 2005 et 2008 sont conçus pour l'entreposage de données et devraient donc bien se préformer dans ces conditions.

Si vous avez un modèle de données qui nécessite souvent d'écrire sur la base de données, le meilleur choix serait d'avoir une table active et une table d'archivage que vous mettez à jour par lots à intervalles réguliers.

3

Votre table est très étroite et fonctionnerait probablement dans une seule table correctement indexée qui ne dépasserait jamais la capacité de SQL Server dans un modèle OLTP normalisé traditionnel, même pour des millions et des millions de lignes. Même avec les avantages du modèle à table double, vous pouvez réduire les avantages en utilisant le partitionnement de table dans SQL Server. Donc, il n'a pas beaucoup à recommander sur le modèle de table unique. Ce serait un scénario Inmon ou "Enterprise Data Warehouse". Dans des scénarios beaucoup plus importants, je transférais régulièrement les données dans un entrepôt de données (modélisé avec un modèle dimensionnel de type Kimball) et je purgeais simplement les données en temps réel - dans certains scénarios simples comme le vôtre, il pouvait effectivement y avoir NO données en direct - tout va directement dans l'entrepôt. Le modèle dimensionnel présente de nombreux avantages lorsqu'il s'agit de découper des données de différentes manières et de stocker un grand nombre de données dans une variété de dimensions. Même dans le scénario d'entrepôt de données, les tables de faits sont souvent partitionnées par date. Il peut sembler que vos données ne correspondent pas à celles-ci (la ville et la date sont vos seules dimensions explicites). Cependant, dans la plupart des entrepôts de données, les dimensions peuvent flamber ou être redondantes. au moment de la charge au lieu de flocon de neige pour plus d'efficacité - comme État, code postal, WasItRaining, IsStationUrban (artificiel). Cela peut sembler stupide, mais lorsque vous commencez à extraire les données pour obtenir des résultats dans des entrepôts de données, vous vous posez des questions comme - un jour où il pleuvait en milieu urbain, quelle était la température moyenne dans le Maine? - c'est juste un peu plus facile à obtenir sans avoir à rejoindre tout un tas de tables (c'est-à-dire qu'il ne nécessite pas beaucoup d'expertise sur votre modèle normalisé et fonctionne très rapidement). Un peu comme des statistiques inutiles au baseball - mais certaines s'avèrent apparemment utiles.

0

Si vous stockez tous dans un tableau, comment allez-vous faire une base de données relationnelle.

Exemple:

id -------------- GUID ---- PK

record_id ------- GUID

chaque fois un nouvel enregistrement sera inséré le [id] changera mais [record_id] restera le même. Maintenant, si vous devez le lier avec la table d'adresse, comment allez-vous faire cela?

Questions connexes