2010-09-03 3 views
4

Je souhaite représenter des documents dans une base de données. Il existe plusieurs types de documents. Tous les documents ont certaines choses en commun, mais tous les documents ne sont pas identiques.Structure de données appropriée pour maintenir une relation un-à-plusieurs

Par exemple, disons que j'ai une table de base pour les documents ...

TABLE docs (
    ID 
    title 
    content 
) 

Maintenant que j'ai un sous-ensemble de documents qui peuvent appartenir à un utilisateur, et qui peuvent avoir des informations supplémentaires associées à leur. Je pouvais faire ce qui suit ...

TABLE docs (
    ID 
    userID -> users(ID) 
    title 
    content 
    additionalInfo 
) 

... mais cela se traduira par un grand nombre de valeurs NULL dans la table, comme seul certains documents peuvent appartenir à un utilisateur, pas tous. Ainsi, au lieu que j'ai créé une deuxième table « ownedDocs » pour étendre « docs »:

TABLE ownedDocs (
    docID -> docs(ID) 
    userID -> users(ID) 
    additionalInfo 
) 

Je me demande: Est-ce la bonne façon de le faire? (Je suis inquiet parce que tout est dans une table, j'ai une relation un-à-plusieurs entre les docs et les utilisateurs.Cependant, en créant une nouvelle table ownedDocs, l'infrastructure de données ressemble à une relation many-to-many entre docs et les utilisateurs - qui ne se produiront jamais)

Merci d'avance pour votre aide

Répondre

2

« en créant une nouvelle ownedDocs de table, la structure de données on dirait que j'ai un plusieurs à plusieurs entre docs et les utilisateurs - qui ne se produira jamais.) »

Si vous faites OwnedDocs.DocId la clé primaire, il sera tout à fait clair que 1: Si nous avons juste la relation N est impossible

La modélisation de zéro ou un à une relation est délicate la.. un sous-type, puis la table unique avec des colonnes NULL est une approche raisonnable, mais il est recommandé de s'assurer que les attributs des sous-types ne sont remplis que lorsque cela est approprié, ce qui impliquerait une contrainte de vérification pour appliquer cette règle:

check (userID is not null or AdditionalInfo is null) 

Ou peut-être même cette règle :

check ((userID is not null and AdditionalInfo is not null) 
     or (userID is null and AdditionalInfo is null)) 

La relation entre les attributs ne seront pas visibles dans un ERD (sauf si vous utilisez une convention de nommage). Pour sûr, la nature obligatoire de AdditionalInfo pour les documents possédés ne sera pas évidente dans le second cas.

Une fois que nous avons plusieurs de ces sous-types, le cas pour des tables séparées devient convaincant, en particulier si les sous-types constituent un arc par exemple. Un document peut être un document financier ou un document médical ou un document personnel, mais pas plus d'une catégorie. Une fois, j'ai implémenté un tel modèle en utilisant une seule table avec beaucoup de colonnes nulles, des vues et des contraintes de vérification. C'était horrible. Les tables de sous-types sont définitivement la solution.

+0

Merci - spécifier le docID comme clé primaire dans la sous-table est une solution élégante. – Travis

3

la structure de données semble que j'ai plusieurs à plusieurs entre documents et utilisateurs -. qui ne se produira jamais.

Entendue, alors vous devez avoir le code d'utilisateur dans le tableau docs pour assurer un à-plusieurs (un utilisateur, potentiellement de nombreux documents).

Je ne vois pas le mal dans les colonnes d'informations supplémentaires étant nul si un document n'est pas associé à un utilisateur particulier, noté par la colonne userid étant nulle. Diviser les informations supplémentaires à une autre table signifie toujours une relation un-à-un, donc il est préférable d'utiliser une table avec doc, utilisateur et informations supplémentaires ...

1

Cela dépend du niveau de normalization que vous voulez atteindre. En règle générale, sur la base de la description que vous fournissez, je repose mon DB comme ceci:

table docs (id, title, content); 
table users (id, ...); 
table users_docs (doc_id, user_id); 
table doc_info(doc_id, additional_info); 

Quelqu'un me corriger si je me trompe, mais cela devrait être 3ème forme normale. Cela garde la structure agréable et propre et n'utilise que les bits requis pour stocker les données comme prévu. Vous pouvez stocker tous les éléments de manière indépendante mais liés si nécessaire.

Selon la nature de l'information supplémentaire, vous devez apporter quelques modifications. Par exemple, les informations supplémentaires correspondent-elles TOUJOURS à un utilisateur? Sera-t-il toujours fourni si le document est associé à un utilisateur? Si c'est le cas, vous pouvez l'ajouter à la table users_docs. Mais cela devrait au moins vous montrer la normalisation.

+0

Votre schéma est exactement comme je l'ai fait. Mais, comme je l'ai dit, je crains de perdre l'expression d'une relation un-à-plusieurs dans la structure de données elle-même. Même si un document ne peut appartenir qu'à un utilisateur, lorsque la structure de données est complètement normalisée, comme dans le cas précédent, cette relation n'est plus claire. Je suppose que je me demande: Quelle est la méthode la plus "appropriée"? – Travis

+0

Hmmm. Peut-être ajouter le doc_id dans users_docs comme clé primaire. Ensuite, il ne peut pas être mis plus d'une fois. –

Questions connexes