Comment gérer la conception de table avec des colonnes variables

17

J'ai un scénario de conception de table et en tant que type non DBA, j'aimerais avoir des opinions sur ce qui est plus évolutif.

Imaginons que l'on vous demande d'enregistrer des informations sur les maisons d'une zone métropolitaine, en commençant par un petit quartier (200 maisons) mais en finissant par atteindre 500 000+ maisons.

Vous devez stocker les informations de base: ID # (un lot unique # que nous pouvons utiliser comme index unique), Addr, City, State, Zip. Une table fine et simple le gèrera.

Mais chaque année, on vous demandera d'enregistrer des informations supplémentaires sur toutes les maisons - et QUELLES informations changeront chaque année. Ainsi, par exemple, la première année, vous êtes invité à enregistrer le nom de famille et la superficie en pieds carrés des propriétaires. La deuxième année, il vous est demandé de conserver le nom de famille, mais de vider la superficie et de commencer à collecter les prénoms des propriétaires.

Enfin - chaque année, le nombre de colonnes supplémentaires change. Pourrait commencer avec 2 colonnes supplémentaires, puis passer à 6 l'année prochaine, puis redescendre à 2.

Ainsi, une approche de table consiste à essayer d'ajouter les informations personnalisées sous forme de colonnes dans les tables maison afin qu'il n'y ait qu'une seule table.

Mais j'ai une situation où quelqu'un a disposé les tables pour cela comme:

Colonnes "Table de la maison": ID, Addr, Ville, État, Zip - avec une ligne par maison

ID   Addr              City     State  Zip 
-------------------------------------------
1    10 Maple Street   Boston      MA  11203

2    144 South Street  Chelmsford  MA  11304

3    1 Main Avenue     Lowell      MA  11280

Colonnes "Tableau d'informations personnalisées": ID, nom, valeur - avec un tableau ressemblant à:

ID   Name             Value

1    Last Name        Smith

2    Last Name        Harrison

3    Last Name        Markey

1    Square Footage   1200

2    Square Footage   1930

3    Square Footage 

Il y a donc plusieurs lignes pour chaque enregistrement de maison individuel. Chaque année, lorsque les informations facultatives requises changent, ce tableau est littéralement reconstruit, donc l'année prochaine il pourrait ressembler à:

1    Last Name    Smith

2    Last Name    Harrison

3    Last Name    Markey

1    First Name   John

2    First Name   Harry

3    First Name   Jim

Finalement, vous accumulez 100 000 rangées de maisons ET un an, il y a 10 informations supplémentaires; le deuxième tableau contient maintenant 1 000 000 de lignes d'informations, dont beaucoup contiennent des informations redondantes (description). Dans l'ensemble, les exigences de la base de données sont que les utilisateurs devront obtenir des informations sur la ligne de la maison + les valeurs de champ personnalisé associées des milliers de fois par jour.

Donc ma question: Serait-ce une mauvaise (ou horrible) pratique de plutôt:

A) Disposez la table de la maison avec une estimation du nombre maximum de colonnes personnalisées (appelées peut-être "1" à "10") et insérez ces valeurs personnalisées directement dans les lignes de la maison

OU

B) Stockez les informations personnalisées dans la table de la maison, mais chaque année lorsque les exigences changent, reconstruisez la table de la maison avec uniquement le nombre de colonnes nécessaires pour les informations personnalisées, avec l'idée que les exigences pourraient devenir folles et vous ne savez jamais combien de maximum des champs facultatifs peuvent être demandés?

Merci, j'espère que cela a du sens!

Schmitty23
la source
Salut, comment avez-vous géré votre problème? J'exécute dans le même genre de scénario et je suis sur le point de créer une table relationnelle par info supplémentaire, et de le rendre avec des vues comme une "table unique".
Benj

Réponses:

15

Vous avez à peu près 4 choix:

NoSQL - définition Chaque enregistrement est stocké sous la forme d'un ensemble de paires clé / valeur. Il est très flexible et rapide. Tous les rédacteurs de rapports ne prennent pas en charge ce style de stockage. Il existe de nombreux exemples d'implémentations de bases de données de NoSQL. Celui qui semble être le plus populaire en ce moment est MongoDB.

EAV - définition C'est là que vous tournez la table entière ou une partie (dans une autre table) sur le côté. C'est un bon choix si vous avez déjà une base de données relationnelle en interne dont vous ne pouvez pas vous éloigner facilement. L'exemple de table d'informations personnalisé que vous avez donné est un bon exemple de table EAV.

Tables standard avec colonnes XML - Considérez cela comme NoSQL rencontre les tables relationnelles. Les données stockées dans une colonne XML peuvent être n'importe quel format pris en charge par XML, y compris plusieurs sous-données corrélées. Pour les colonnes que vous savez être des colonnes "normales", elles peuvent être construites comme le type de colonne approprié pour stocker les données (Nom, Adresse, Ville, État, etc.).

Tables standard avec beaucoup de colonnes supplémentaires - Vous avez une base de données relationnelle, vous ne pouvez pas utiliser XML ou EAV, et NoSQL n'est pas une option. Ajoutez de nombreuses colonnes supplémentaires de chaque type. Je suppose que 30 varchar ou plus, 30 entiers ou plus, 15 ou plus numériques. Et une fois que vous utilisez une colonne pour une valeur, ne la réutilisez pas . Et ne supprimez pas non plus la colonne .

De toutes ces solutions, mon opinion personnelle est que vous trouverez l'approche NoSQL ou EAV la plus réussie avec le moins de refactorisation de votre code et de votre schéma.

Vous aurez une situation où vous collectez des données un an, pas le suivant, puis les recueillez par la suite. Essayer de mettre à jour les anciennes données avec les informations correctes est problématique et coûteux. Le stockage n'est ni l'un ni l'autre.

Adam Zuckerman
la source
J'ai entendu dire que vous pouvez également utiliser des tableaux croisés dynamiques ou quelque chose comme ça
Alexander Mills
2

Pour répondre à votre question sur ces 2 options, aucune ne me semble juste. A) vous enfermera et B) est beaucoup de travail. Le schéma actuel que vous décrivez n'est pas trop mauvais (sauf pour avoir le nom de l'information ("prénom", "pied carré", etc.) comme chaîne au lieu d'un ID référencé dans une table de recherche.

Cependant, cela me semble être un bon candidat pour une base de données NoSQL ( http://en.wikipedia.org/wiki/NoSQL ). Bien que je n'ai jamais travaillé avec une telle base de données, ce que vous décrivez est un scénario typique que cela résout.

ETL
la source
0

Si le nombre simultané de colonnes personnalisées est fini et que les limites sont connues (par exemple pas plus de 10-20 colonnes personnalisées pour les chaînes, pas plus de x colonnes pour les entiers, etc.)
Vous pouvez utiliser la table de base avec des champs supplémentaires par type de données et à la place de recréer le tableau chaque année, créez une vue pour cette année en incluant uniquement les colonnes personnalisées pertinentes et en renommant les champs génériques pour refléter le contenu de cette année.

House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...

create view house_2014 as 
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...

Le problème avec cette approche est que vous n'avez pas d'historique mais que vous pouvez facilement en faire une copie chaque année avant de modifier les exigences de colonne.

create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";
scheelec
la source
0

Pouvez-vous énumérer tous les scénarios pour lesquels vous souhaitez stocker ces données?

s'il y a un nombre fini de combinaisons de colonnes qui peuvent être appliquées à la table, essayez de modéliser une "table de base" avec des colonnes communes qui doivent s'appliquer à tous les scénarios, puis créez plus de tables (pour implémenter une sorte d'héritage; ceci est connu sous le nom de sous-type / supertype dans la conception ERD et de base de données.)

une table pour chaque scénario, de cette façon au moins vous garderez les tables propres et vous pourrez éviter d'avoir l'adresse municipale stockée dans la colonne "nom" ...

jetez un oeil à cette question de conception: /programming/554522/something-like-inheritance-in-database-design

Joe
la source