web-dev-qa-db-fra.com

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

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, City, State, 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 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

OR

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!

17
Schmitty23

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 soit la table entière soit une partie (dans une autre table) de son 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.

15
Adam Zuckerman

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.

2
ETL

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 la 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: https://stackoverflow.com/questions/554522/something-like-inheritance-in-database-design

0
joe

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.)
.

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";
0
scheelec