2009-09-27 5 views
1

Je suis en train de concevoir un système de gestion de documents pour une école (SQL & .NET). L'école possède différentes données qu'elle souhaite stocker, telles que le personnel, les élèves, les finances, etc. Le système devrait pouvoir joindre un document à n'importe quel enregistrement du système quel que soit son type (personnel, élève ...)Comportement OO pour une base de données ER (relation un-à-plusieurs pour plusieurs tables)

Une manière typique d'ER de faire ceci serait de créer des tables de types différentes (personnel ...) ainsi qu'une table Documents. Pour associer les enregistrements de table de type aux enregistrements de document, il faut une "table de liens" telle que PersonnelDocuments, avec les colonnes PersonnelID et DocumentID. Je trouve cette approche un peu maladroite car il pourrait y avoir des centaines de tables de types (dans les systèmes futurs) qui auraient chacune besoin d'une table de liaison. Existe-t-il une façon plus générique de le faire, tout en respectant la conception ER DB appropriée.

+0

Duplicata de http://stackoverflow.com/questions/695752/product-table-many-kinds-of-product-each-product-has-many-parameters/ –

Répondre

1

Une solution consiste à rendre votre identifiant unique si grand que chaque objet de la base de données possède un identifiant unique quel que soit le tableau dans lequel il se trouve (le GUID est souvent juste cela). Une fois que vous avez un identifiant unique pour chaque objet, vous n'avez besoin que d'une seule table de liens. J'ai utilisé cette approche pour une application qui vous obligeait à pouvoir publier des commentaires sur n'importe quel objet dans la base de données, et comme vous l'avez fait, j'ai trouvé que des dizaines de tables nommées XXXXComments et YYYYComments ne le coupaient pas. Cette solution a bien nettoyé les choses. Une autre approche que j'ai utilisée dans le passé est de faire en sorte que toutes les tables qui requièrent un lien de documents dérivent de la même table de base. Cette approche est souvent assez maladroite en elle-même, sauf si votre domaine est plutôt petit, ou si la section nécessitant le lien documents est autonome. Si je me souviens bien, je créais une application de suivi des rapports dans laquelle il y avait plusieurs types de rapports, chacun pouvant être transmis à différents groupes de l'entreprise, puis renvoyé et transmis à d'autres groupes jusqu'à ce que tous les éléments nécessaires soient acquis. En traitement. J'ai fini par créer une table de base de rapport et ma table de lien pour les avants a utilisé cet ID au lieu de créer une table d'avances pour chaque type de rapport.

0

Vous décrivez le système en tant que système de gestion de documents. Une solution serait alors d'honorer la primauté de la nature documentée des entités dans le système. Le modèle suivant définit une entité abstraite qui sert de parent pour une table de documents et de super-type pour un ensemble de tables de sous-types. Ce modèle vous permet d'associer n'importe quel nombre de documents avec un DocumentedThing.

DocumentedThing 
--------------- 
ThingId  Integer primary key 
ThingType String check (ThingType in ('PUPIL', 'STAFF')) 
      unique key (ThingId, ThingType) 

Document 
-------- 
ThingId  Integer foreign key references DocumentedThing (ThingId) 
DocumentId Integer primary key 
Text   Clob 

Pupil 
----- 
PupilId  Integer primary key 
ThingId  Integer unique key 
ThingType String check (ThingType = 'PUPIL') 
Name   String 
DateOfBirth Date 
      foreign key (ThingId, ThingType) 
       references DocumentedThing (ThingId, ThingType) 

Staff 
----- 
StaffId  Integer primary key 
ThingId  Integer unique key 
ThingType String check (ThingType = 'STAFF') 
Name   String 
HireDate  Date 
      foreign key (ThingId, ThingType) 
       references DocumentedThing (ThingId, ThingType) 

L'échafaudage de clés uniques assure qu'un DocumentedThing peut avoir un dossier dans les deux Staff ou Pupil mais pas les deux. De plus, il ne peut y avoir plusieurs enregistrements dans la table de sous-types. Un enregistrement dans Staff peut uniquement correspondre à un enregistrement dans DocumentedThing qui a la valeur 'STAFF' dans ThingType. La seule chose qui est difficile à appliquer est l'insistance qu'un DocumentedThingdoit avoir un enregistrement de sous-type. Cela peut être fait, mais il est généralement compliqué, et dépend dans une certaine mesure de votre choix de produit SGBD.

L'ajout d'un nouveau sous-type a un impact minimal: outre l'ajout de la table réelle pour contenir ses informations, il suffit d'ajouter une nouvelle valeur à DocumentedThing.ThingType; Si vous avez beaucoup de sous-types, vous pouvez choisir de restreindre cela avec une clé étrangère à une table de consultation plutôt qu'une contrainte de vérification.

Questions connexes