2009-03-04 5 views
0

Disons que vous avez les entités suivantes dans votre base de données:Comment structurez-vous vos entités que vous avez l'intention de réutiliser?

Image http://lh6.ggpht.com/_UpGtM3B8h1U/Sa7SqfWmgDI/AAAAAAAAAHE/epqtm7EnoFg/test.gif

Vous voulez être en mesure d'ajouter une note à tous les trois des autres tables d'entités (utilisateur, client et projet). Comment voulez-vous mettre cela en place?

  1. Ajouter un tableName et un FKId à la table de notes?
  2. Créer une table distincte pour chaque groupe note associée (ie., ClientNote, UserNote)
  3. Créer un champ distinct dans la note pour chaque clé étrangère (UserId, ClientId, etc.)

me semble être aller et venir entre les options 2 et 3, bien que je serais en place pour 1 s'il y avait une mise en œuvre élégante. L'option 2 est intéressante car il n'y a pas de null. L'option 3 est attrayante parce qu'une note ressemble à une note, peu importe à quoi elle est associée.

Des pensées?

+0

l'image semble manquer. – webclimber

Répondre

1

Je voudrais généralement aller avec l'option 2. Je ne souligne pas le nombre de tables dans une base de données dans la raison.

La grande question est, ces notes vont-elles être traitées comme un seul article? Par exemple, allez-vous dire: "Montrez-moi toutes les notes, que ce soit pour un client, un utilisateur ou un projet." Je ne peux pas penser à des situations où cela serait utile. Vous allez généralement dire «Montrez-moi les notes de ce client» ou «Montrez-moi les notes de ce projet».

Puisqu'il ne s'agit pas logiquement d'un élément, je suggère de ne pas essayer de les modéliser physiquement comme un seul élément.

+0

Je commence à penser que l'option 2 est probablement la voie à suivre. 1 est en quelque sorte démoli parce que j'essaierais d'imposer l'intégrité avec une clé correspondant au nom d'une table - c'est vraiment mal. Entre 2 et 3, le manque de null est très convaincant. – anopres

+0

Deux admirables objectifs (faire respecter l'intégrité et d'éviter NULLs si possible) :) Je suis allé dans des situations où je devais traiter avec une solution 1 et il est presque toujours causé des maux de tête. –

0

La façon dont j'ai l'habitude de voir cela est traitée dans l'option 1. L'avantage est que c'est un moyen assez facile pour les humains impliqués de voir ce qui se passe. Comme vous l'avez dit, l'inconvénient est que le SQL devient un peu moins élégant.

C'est juste un peu comment ça se passe, cependant. En réalité, même si cela peut sembler un peu maladroit, les requêtes résultantes sont claires et lisibles. Vous n'aurez qu'à ajouter sql au nouveau code, au fur et à mesure, dans les zones où vous avez ajouté de nouvelles tables.

Lorsque vous manipulez des notes directement, vous n'avez à gérer qu'une seule table.

+0

Hmmm .... 1 était en fait ma méthode moins préférée car il est difficile d'utiliser les outils de bases de données pour maintenir l'intégrité référentielle. – anopres

+0

Les outils de base de données ne peuvent vous emmener que jusqu'à présent. Si vous le voulez dans la base de données, vous devrez probablement utiliser des déclencheurs ou une autre méthode spécifique au vendeur (les règles de Postgres sont mes préférées). – SingleNegationElimination

0

Il y a une quatrième méthode (que je recommande): ajouter un identifiant unique à la table Note et un NoteID de champ à l'utilisateur, le client et le projet

+0

J'aimerais pouvoir ajouter plusieurs notes à chaque entité. J'aurais dû mettre cela dans la question initiale. – anopres

0

Que font peut dépendre du fait que les notes que vous champs le besoin est vraiment le même entre les entités. Si elles sont identiques, j'aurais probablement une table Notes (alors si les besoins changent toutes les notes obtiennent un champ de date de révision, par exemple, ajouté en une étape) avec un Notetype (utilisateur, client, projet), noteID, et id de la table appropriée ainsi que tous les champs connexes de notes dont vous avez besoin. Le plus gros problème avec ceci est que les relations FK devront être gérées via un trigger au lieu d'un FK. Vous ne voulez pas mettre un ID utilisateur invalide, mais comme la colonne entière ne contient pas d'ID utilisateur, vous ne pouvez pas simplement configurer une relation FK. D'un autre côté, si vous ajoutez une autre entité plus tard, vous pouvez faire sans affecter la structure de votre table (bien que vous deviez encore modifier le déclencheur), ce qui pose le problème d'avoir les identifiants dans des champs séparés. Cela signifie également que vous ne pourrez pas utiliser la mise à jour en cascade ou la suppression, ce qui peut compliquer la suppression d'enregistrements (ou la modification d'une clé naturelle (tremblement)).

Si les besoins pour les champs que vous avez pour les notes sont différents entre les entités, je créerais des tables de notes distinctes pour chaque entité.

Si vous souhaitez afficher la table Notes dans chaque requête entre toutes les entités, vous pouvez également utiliser des tables distinctes pour chaque entité afin de réduire les problèmes de blocage et de blocage. Les notes, cependant, peuvent ne pas avoir besoin d'être frappées aussi souvent, alors ce n'est peut-être pas une si mauvaise situation.

0

Option 3. Avoir une identité en tant que clé primaire et avoir une colonne de clé étrangère pour toutes les tables qui partagent la table Note. Je gère le courriel, le téléphone, l'adresse, etc. de cette façon.

Le seul inconvénient que je sais si vous avez 10 tables liées à Note - vous auriez 10 colonnes de clé étrangère. Le problème que j'ai avec l'option 1 est que j'ai l'impression de créer une clé étrangère artificielle (avec TableName/Pkid, qui ne fait pas partie des clés primaires User/Project, qui ne sont que Pkid). C'est peut-être mon parti pris personnel, je n'ai jamais eu l'impression que c'était un bon design, mais je ne pouvais pas vraiment dire pourquoi.

0

Je pense que vous devriez définitivement éviter la solution 1 dans ce cas.
Vous perdez la référence d'intégralité, il devient impossible d'interroger votre base de données sans SQL dynamique et vous avez toujours besoin de 2 requêtes pour sélectionner quelques notes!
Vous ne devriez jamais utiliser de cette façon dans des cas simples comme ici. Comme je le vois, je vais avec l'option 4 (en ajoutant un champ note_id sur le projet, le client et l'utilisateur). Si vous avez besoin de plusieurs notes pour une ligne, ce n'est pas un problème. Vous ajoutez simplement une table supplémentaire (disons note_set) qui fait la relation n-1.

client (client_id, note_set_id) utilisateur (user_id, note_set_id) du projet (project_id, note_set_id)

note_set (note_set_id) Note (note_id, note_set_id, titre, corps)

le problème majeur de cette solution, est-ce donné une note que vous ne pouvez pas trouver l'initiale "entité" sans faire une union sur les trois tables. Il ne semble pas un gros problème pour moi, mais, si elle est, puis aller avec l'option 3.

Enfin, l'option 2 est bon aussi bien, mais ce n'est pas ce que j'appelle « réutilisation ».

Veuillez excuser mon anglais.

Questions connexes