2009-03-11 8 views
3

J'ai rencontré ce problème dans toutes les applications que j'ai écrites. Je voudrais une réponse finale par consensus!Comment puis-je stocker des méthodes de contact (ou des données typées similaires avec différents champs) de manière normalisée?

Est-ce la façon la plus normalisée/efficace/appropriée pour stocker les méthodes de contact ou d'autres données le long de ce modèle dans une base de données?

Contact { PK ContactId, ... } 

ContactContactMethod {PK FK ContactId, PK FK ContactMethodId, Key, Comments } 

AddressContactMethod {PK FK ContactMethodId, Line1, Line2, City, State, Zip } 
EmailContactMethod {PK FK ContactMethodId, EmailAddress } 
InstantMessengerContactMethod {PK FK ContactMethodId, IMClient, IMAddress } 
PhoneContactMethod {PK FK ContactMethodId, ... } 
WebsiteContactMethod {PK FK ContactMethodId, ... } 
OtherContactMethod {PK FK ContactMethodId, ... } 

Dois-je envisager un champ Xml pour ContactMethodData sur la table ContactContactMethod à la place?

Quelque chose se sent mal à propos AddressContactMethod, EmailContactMethod, etc tous partageant la même unicité des clés primaires.

pensé aussi sur une clé, paire de valeurs pour les données de contact, mais ce serait encore plus d'une douleur à la requête que le champ Xml.

(Directives de conception: chaque contact peut avoir plus d'un ou aucun de chaque type de méthode de contact, chacun avec une "clé" non unique comme "maison, travail, voiture rouge, etc" et commentaires mais aucun autre éléments de données entre les types)

+1

Cela m'intéresse. Il semble que vous ayez un design décent, cependant, il couvre tous les cas que je peux penser à partir de vos lignes directrices de conception. Je suis d'accord avec votre commentaire sur XML et les données clé/valeur - celles-ci commencent à aller à l'encontre de l'objectif de la base de données. –

+0

Juste curieux - pourquoi avez-vous le PK FK ContactMethodId sur tous les Adresse/Email/etc. les tables? Y aurait-il une table de base de ContactMethod à laquelle ils sont tous liés, ou pourraient-ils se suffire à eux-mêmes? –

+0

@Andy ils sont liés à la table ContactContactMethod, qui sera probablement celui d'attribuer l'identité –

Répondre

2

Comme vous, je l'ai vu plus que ma part des modèles de base de données d'information de contact Je pense que le vôtre est assez raisonnable, et voici cater la colonne Clé séparément des tableaux * Méthode est une bonne idée, permettant de grouper les adresses e-mail et les adresses postales "maison" d'une manière.

Cependant, je pense que la plupart des bases de données de contacts sont sur-architecturées. Bien que je ne sois pas d'accord avec l'approche de Chris Lively, je pense que vous pourriez simplifier en ayant simplement des types d'informations de contact (e-mail, téléphone, URL web, etc) et en stockant une chaîne de texte simple pour chacun. Essayer de valider les types séparés ou de les décomposer en sous-champs ne vaut généralement pas la peine. D'une part, toutes les règles de validation des numéros de téléphone et d'adresses sont immédiatement affichées si vous autorisez les contacts à l'extérieur des États-Unis. Stocker l'adresse complète dans une chaîne Unicode, et j'espère que le meilleur est mon conseil.

laisse quelque chose que de la conception comme ceci:

Contact { PK ContactId, ... } 
ContactType { PK ContactTypeId, ContactType } 
ContactMethod {PK FK ContactId, PK FK ContactTypeId, PK Key, Value, Comments } 

Le ContactMethod.Value est la valeur du texte.

Cela semble similaire à la façon dont Google effectue le suivi des contacts à tout le moins. Et si rien d'autre, ils ont probablement réfléchi au problème de garder trace de zillions de contacts de chaque nation sur Terre.

+0

@yukondude C'était ma première approche, mais que se passe-t-il lorsque le client x demande un rapport géographique sur l'emplacement de ses contacts par code postal ? Ou veut extraire des courriels à des fins de marketing? On dirait que je triche le db hors des index. Je suppose qu'il pourrait être miné et refactorisé alors. –

+0

@divitiae L'extraction des e-mails fonctionne toujours (l'un des types de contact serait "e-mail") mais vous avez raison sur le code postal (que nous n'avons pas ici au Canada, ni ailleurs, mais i18n isn n'est pas toujours nécessaire). Sortir le ZIP dans une colonne séparée vous ramène tout de suite au carré 1. – yukondude

0

La plupart des gens font vraiment des choses d'architecte. Regardez de cette façon, combien de numéros de téléphone pour un contact particulier vous intéressent vraiment? Habituellement 1; parfois 2.

Même chose pour les adresses, généralement tout ce que vous avez vraiment besoin est celui dans le dossier.

Donc, dans cet esprit, regardez votre application. Si vous avez seulement 2 numéros de téléphone, stockez-les dans le tableau CONTACT comme HomePhone, WorkPhone ou autre. Si, à un certain moment dans le futur, vous déterminez que vous avez besoin de plus de numéros de téléphone, alors allez-y et répartissez les numéros dans un tableau séparé. Idem pour les adresses. Pareil pour l'email.

La réalité est que la plupart de l'interface utilisateur ne montrent pas les numéros de téléphone dans une grille. Au lieu de cela, ils sont alignés sur le nom de la personne. La raison en est que vous n'avez besoin que de quelques chiffres. En résumé: gardez la base de données aussi simple que possible. L'équipe de l'interface utilisateur et votre serveur de base de données vous en seront reconnaissants.

+0

@Chris Je suis d'accord avec tous les points que vous avez soulevés, mais dans notre cas, notre interface utilisateur supportera plusieurs entrées pour chaque type de méthode de contact d'une manière qui ne sera pas aussi déroutante qu'une grille pour l'utilisateur. Il est également important pour nous que nous leur permettons de les étiqueter ce qu'ils ne veulent pas réparer. Accueil, Travail –

1

Dans l'ancien temps, je serais allé avec un schéma de la table - quelque chose comme:

Person [ID, Name] 
ContactPoint [ID, PersonID, ContactMethod] 
EmailContactPoint [ID, EmailAddress] 
AddressContactPoint [ID, Line1, Line2, blah] 

Avec un 1-1 relation entre les différents points de contact et la table ContactPoint - une sorte d'héritage. Les ORM comme Hibernate/NHibernate et Entity Framework peuvent instancier le type correct en fonction de ces relations 1-1.

De nos jours, j'utiliserais probablement un blob XML et quelques fonctions en SQL pour faciliter le traitement du point de contact par défaut/principal pour un type particulier (par exemple, "GetPrimaryPhoneNumber (personID)".

1

La réponse finale consensuelle est que la réponse de chacun est la meilleure et que personne d'autre ne vaut un centime.C'est le problème, il n'y a pas une seule façon qui convient à tous les besoins. dernière réponse consensuelle -.. peut-être même pas une réponse consensuelle, mais certainement pas une dernière

2

Il y a un nom pour ce modèle. C'est ce qu'on appelle la «généralisation de la spécialisation».

Dans ce cas, les méthodes de contact sont des moyens spécialisés de contacter un contact.

Une recherche web sur "la généralisation de la spécialisation en design relationnel" vous mènera à quelques articles traitant de ce modèle de manière plus générale. Pour une vue de l'objet ou du même motif, recherchez "generalization specialization object design".