2010-01-07 8 views
0

Je cherche un petit conseil sur la façon de configurer une base de données pour stocker des données numériques pour une application de modélisation. Mes utilisateurs disposent d'une feuille de calcul contenant des données à utiliser dans une application de modélisation. Les données sont structurées comme suit: Chaque onglet est un secteur d'activité, les colonnes sont des années et les lignes sont des éléments. Les cellules sont des nombres décimaux standards xx.xx etc.Modèle de base de données pour les données semi-structurées

 2005 2006 2007 2008 2009 2010 2011 2012 
data1 2.5 3.5 
data2  
data3 

La deuxième application peut recevoir des données soit un lien ole à partir d'Excel ou d'une requête odbc. J'aimerais placer les données dans une base de données (serveur sql ou oracle) mais je ne sais pas comment structurer les tables en équilibrant la façon dont les données pénètrent dans la base de données, les interactions utilisateur et les requêtes en sortie vers la deuxième application. Le secteur d'activité, les éléments et les années ne sont pas tous fixes.

Je sais que c'est fondamentalement un tableau croisé dynamique de sorte que la réponse que je regarde est une table avec {ligne, élément, année, valeur}. Étant donné les problèmes liés à l'entrée et à la sortie de données avec ce format, serais-je mieux avec une table de {line, element, year1..yearx} avec un nombre arbitraire de colonnes pour les années à venir? Ce n'est pas un cas classique de valeur d'attribut d'entité mais quelque peu similaire. Les éléments ne changent pas très souvent mais il y en a un grand nombre 300+. Je pourrais les regrouper dans des tables séparées et utiliser une structure comme {line, year, element1..elementX} Ce serait probablement le plus simple à développer, mais ne semble pas "juste".

Les requêtes de sortie sont généralement conservées dans un seul élément de données avec ligne, année et valeurs transmises à la deuxième application via odbc.

Répondre

0

Puisque vous prévoyez d'utiliser une base de données relationnelle système de gestion, je stockerais ces données dans un ensemble de tables normalisées. Un premier coup de poignard vient avec (tout cela est basé sur SQL Server 2005, et désolé,):

CREATE TABLE MyData 
(
    LineOfBusiness varchar(50) not null 
    ,Year   smallint  not null 
    ,Element   varchar(50) not null 
    ,Value   float  not null 
    ,constraint PK_MyData 
    primary key (LineOfBusiness, Year, Element) 
) 

Avoir deux varchar (50) s dans votre clé primaire pourrait être considérée comme inefficace, en particulier si vous finissez avec beaucoup de données. (a) Je n'irais pas jusqu'à ce que vous atteigniez 64k, mais (b) au moment où vous atteindrez des mégaoctets de données, il sera beaucoup trop tard pour revenir en arrière et réviser votre architecture - cela pourrait aussi bien c'est la première fois.

Il pourrait être efficace pour se déplacer LineOfBusiness à une table de recherche:

CREATE TABLE LineOfBusiness 
(
    LineOfBusinessId int   not null 
    constraint PK_LineOfBusiness 
    primary key 
    ,Description  varchar(50) not null 
) 

Si « éléments » peuvent être répétés entre les secteurs d'activité, il est certainement plus efficace pour le déplacer vers une table de recherche:

CREATE TABLE Element 
(
    ElementId int   not null 
    constraint PK_Element 
    primary key 
    ,Description varchar(50) not null 
) 

Année est une simple valeur numérique se situant entre 1900 et 2100 (et sinon, hein?), donc il n'y a pas besoin de normaliser dehors. L'utilité d'une table de conversion pour l'année dépend des exigences de l'application. (Peut-être avoir des colonnes et lastyear dans de première année LineOfBusiness logique?)

Sur la base des deux tableaux ci-dessus et de travailler dans l'intégrité relationnelle, vous finiriez avec

CREATE TABLE MyData 
(
    LineOfBusinessId int  not null 
    constraint FK_MyData__LineOfBusiness 
     foreign key references LineOfBusiness (LineOfBusinessId) 
    ,Year    smallint not null 
    ,ElementId   int  not null 
    constraint FK_MyData__Element 
     foreign key references Element (ElementId) 
    ,Value    float  not null 
    ,constraint PK_MyData 
    primary key (LineOfBusinessId, Year, ElementId) 
) 

Cela laisse beaucoup de questions ouvertes sur la façon de charger les données et assurer/préserver validité, et bien sûr les requêtes (et probablement les requêtes de pivot) devront être écrites, mais vous pouvez tourner les roues et ne rien faire si vos conceptions de stockage initial sont inadéquates.

2

Ce n'est pas un EAV, c'est un antipattern différent que j'appelle Metadata Tribbles. Autrement dit, ils semblent amicaux et pratiques, mais ils ont tendance à se multiplier hors de contrôle.

Définissez une deuxième table avec l'année comme une colonne, la valeur de données numériques comme une colonne supplémentaire.

N'essayez pas d'écrire une requête pour toutes les valeurs d'élément pour une ligne donnée sur la même ligne de résultat. Au lieu de cela, utilisez une requête qui renvoie plusieurs lignes et écrivez du code d'application pour les parcourir afin de collecter toutes les valeurs dont vous avez besoin.

+1

Ou utilisez un tableau pivotant. Ils ne sont pas difficiles à faire dans le serveur SQL. –

1

Peut-être quelque chose comme ceci:

lineofbusiness = (id, name) 
elements = (lineofbusinessid, year, value) 

donc la table des éléments pourrait ressembler à ceci:

 
    lineofbusinessid year value 
     1    2009 2.3 
     1    2010 4.0 
     1    2011 1.0 
     2    2009 9.0 

etc.

Questions connexes