2009-07-15 8 views
4

Question de conception de base de données pour tous. J'ai un formulaire (comme, le type de papier) qui a plusieurs points d'entrée pour les données. Ce formulaire a changé et devrait changer au fil des ans. Il est en train de devenir une application informatique, de sorte que nous pouvons, entre autres, cesser de gaspiller du papier. (Et des choses mineures, comme avoir toutes les données dans un magasin central qui peut être interrogé, etc.) Je voudrais stocker toutes les données de formulaires dans une base de données, et être assez agnostique quant aux changements.Conception de base de données: Stocker des données à partir de formulaires papier dans la base de données

A l'origine, j'envisagiez chaque champ pour être une chaîne - et j'avais quelque chose comme la table suivante:

FormId int (FK) 
FieldName nvarchar(64) 
FieldValue nvarchar(128) 

... quelque chose comme ça. C'était en fait un peu plus 3NFy en ce que FieldName était dans une autre table, associée à une clé artificielle, de sorte que les noms de champs n'étaient pas dupliqués partout.

Cependant, je voudrais étendre cela aux données numériques et déroulantes. Je pourrais juste stocker des données numériques comme des chaînes, mais cela semble être une idée assez moche. Pareil avec des listes déroulantes. Je pourrais arrêter d'utiliser une table, et utiliser des colonnes sur la table de formulaire principale (celle que FormId référence ci-dessus), mais cela signifie ajouter une colonne pour chaque nouvel élément au fur et à mesure, et les anciens formulaires seraient simplement nul. (Et, à moins que j'emmagasinés, je ne sais pas quand cette colonne a été créé avec la table de chaîne ci-dessus, il est implicite..)

je pourrais étendre le tableau ci-dessus à quelque chose comme:

FormId int (FK) 
FieldName nvarchar(64) 
FieldValueType int -- enum as to which of the columns below are valid (or just let nulls imply that) 
FieldValue nvarchar(128) 
FieldValueInt int 

Les combos devraient être dans un OTLT (une vraie table de correspondance), ce que j'ai des réserves à propos, mais peut-être que c'est nécessaire ici?

Un conseil sur StackOverflow? J'utilise MSSQL, mais c'est vraiment une question plus générale.

Répondre

2

Utiliser les valeurs Null. La conception de base de données appropriée est un sujet compliqué; vous pouvez faire bien de prendre une bonne référence et faire des recherches sur le tout (je comprends this est un bon livre sur le sujet). En général, il semble que vous seriez bien servi en commençant par une seule table qui encapsule tous les champs de votre formulaire, puis en le soumettant au processus de normalisation. Et oui, utilisez des valeurs nulles et n'utilisez PAS un int pour énumérer les colonnes qui ont des valeurs valides; c'est exactement ce que les nulls sont pour.

2

Vous pouvez avoir une table distincte pour chaque type de données.

I.e. pour extraire un formulaire entier, vous feriez une jointure N-way en utilisant l'ID de formulaire où N est le nombre de types de données distincts que vous supportez (+ éventuellement des extras en fonction de l'information souhaitée - par exemple les valeurs déroulantes seront probablement stockées dans une autre table/votre recherche de nom de domaine/etc.)

Mais la conception devrait probablement aussi dépendre de la façon dont vous avez l'intention d'utiliser les données, dont vous n'avez rien dit. Et cela dépendra aussi de la vitesse à laquelle le taux de changement est pour ces formes. . .

1

En créant une table avec une description de vos formulaires, vous définissez en fait une structure de métadonnées. C'est décourageant. Vous auriez besoin d'une grande partie de l'infrastructure nécessaire pour une description correcte de la table. Je pense que les fournisseurs de votre système de base de données ont déployé beaucoup d'efforts pour faire tout cela. Au début, j'ai pensé - quelle bonne idée! Construisez votre propre système de description de table compatible avec la compatibilité!

Mais alors j'ai pensé - je suis trop stupide pour faire ça tout seul. Il doit y avoir un système de base de données capable de le faire. Je conclus donc, n'étant pas un expert en db, de définir les valeurs par défaut correctes pour les «nouveaux champs» dans les nouvelles versions de formulaire. Gérez le problème de compatibilité dans votre logique métier.

1

Je vous déconseille vivement d'avoir une «table générique» comme vous l'avez décrite. Vous réessayez essentiellement la base de données relationnelle, ce qui n'est pas une bonne idée: les requêtes et les mises à jour seront très pénibles avec votre structure, et vous ne pourrez pas utiliser les fonctionnalités plus avancées comme les clés étrangères et les déclencheurs, si vous besoin d'eux.

Créez simplement une ou plusieurs tables avec des colonnes pour les champs de données, et si un formulaire n'a pas de champ, laissez-le être nul. Ou, mieux encore, avoir une "table de base" (champ qui sont sous toutes les formes), et donner des noms/numéros de version aux formulaires mis à jour, et avoir une nouvelle table pour les nouvelles colonnes que cette version ajoute, puis utiliser un PK synthétique pour joindre ces nouvelles tables à votre table de base.

i.e. .:

base table: id(numeric,PK), name, birthday, town 

addresstable1: street, number, postal code, country, base_table_id (foreign key) 

addresstable2: po box no, po box code, base_table_id (FK) 

et ainsi de suite.

De cette façon, vous évitez des charges de champs nulles; vos tables ne sont pas si larges (toujours souhaitables), et vos enregistrements sont implicitement versionnés, car la liste des tables qui ont un enregistrement appartenant à un enregistrement dans votre table de base vous indique les champs du formulaire original, donc quel type de formulaire utilisé à l'origine.

Questions connexes