Question

J'ai besoin de stocker les informations de contact pour les utilisateurs.Je tiens à présenter ces données sur la page comme un hCard et téléchargeable au vCard.Je tiens également à être en mesure de rechercher la base de données par le numéro de téléphone, e-mail, etc.

Que pensez-vous est la meilleure façon de stocker ces données?Étant donné que les utilisateurs peuvent avoir plusieurs adresses, etc normalisation complète serait un gâchis.Je suis en train de réfléchir à l'aide de XML, mais je ne suis pas familier avec l'interrogation XML db.- Je encore être en mesure de rechercher des utilisateurs en contact info?

Je suis à l'aide de SQL Server 2005, si ce qui compte.

Était-ce utile?

La solution

Considérons deux tables pour les Personnes et leurs adresses:

People (pid, prefix, firstName, lastName, suffix, DOB, ... primaryAddressTag )

AddressBook (pid, tag, address1, address2, city, stateProv, postalCode, ... )

La Clé Primaire (qui identifie de manière unique chaque ligne) de Personnes est pid.La pharmacocinétique du Carnet d'adresses est la composition de pid et de la balise (pid, tag).

Certaines données, par exemple:

Les gens

1, Kirk

2, Spock

Carnet d'adresses

1, home, '123 Main Street', Iowa

1, work, 'USS Enterprise NCC-1701'

2, other, 'Mt. Selaya, Vulcan'

Dans cet exemple, Kirk a deux adresses:un "chez soi" et un "travail".L'un de ces deux peuvent (et devraient) être noté comme une clé étrangère (comme une référence croisée) en People dans le primaryAddressTag colonne.

Spock a une adresse unique avec le tag 'les autres'.Puisque c'est Spock seule adresse, la valeur "autre" doit aller dans le primaryAddressTag colonne pid=2.

Ce schéma a le bel effet d'empêcher la personne même de reproduire l'un de leurs propres adresses par hasard en réutilisant les tags alors que dans le même temps, permettant à toutes les autres personnes d'utiliser n'importe quelle adresse les balises qu'ils aiment.

De plus, avec FK références dans primaryAddressTag, la base de données du système lui-même de faire respecter la validité de l'adresse principale de la balise (par l'intermédiaire de quelque chose qui nous de base de données geeks appel d'intégrité référentielle), de sorte que votre -- ou n'importe-l'application n'a pas besoin de s'inquiéter à ce sujet.

Autres conseils

Pourquoi normalisation complète "être un gâchis"?C'est exactement le genre de chose que la normalisation rend moins salissant.

N'ayez pas peur de normaliser vos données.La normalisation, comme Jean mentionne, est la solution et non le problème.Si vous essayez d'éliminer vos données simplement pour éviter un couple rejoint, alors vous allez provoquer vous-même de sérieux problèmes à l'avenir.Essayer de revoir ce genre de données en bas de la ligne, après vous avez une taille raisonnable dataset ne SERA PAS AMUSANT.

Je vous suggère fortement de consulter Les immeubles de grande hauteur à partir de 36 Signaux.Il a récemment été recommandé à moi quand j'étais à la recherche en ligne pour un gestionnaire de contacts.Il est tellement à droite.En fait, ma seule objection à ce jour avec le service, c'est que je pense que les versions payantes sont trop cher-c'est tout.

Aujourd'hui, je ne rentre pas dans un plat profil d'adresse.J'ai 4-5 adresses e-mail que j'utilise régulièrement, 5 numéros de téléphone, 3 adresses, plusieurs sites web et les profils de chat, qui, tous, je voudrais inclure dans mon profil du contact.Si vous êtes de départ pour construire un système de gestion des contacts dès maintenant, et vous êtes non grevés par les contraintes architecturales (pensez à gmail cantacts être conçus pour une seule adresse de courrier électronique), puis faire vos utilisateurs une faveur et rendre votre structure de contact souples (normalisé) que possible.

Cheers, -D.

Je suis conscient de SQLite, mais qui n'aide pas vraiment - je suis en train de parler de déterminer le meilleur schéma (indépendamment de la base de données) pour le stockage de ces données.

Par John, je ne vois pas quel est le problème avec un classique normalisée schéma serait.Vous n'avez pas donné beaucoup d'informations, mais vous dites qu'il y a un un-à-plusieurs relations entre les utilisateurs et les adresses, alors j'aimerais bien dodues pour une tourbière de la solution standard avec une clé étrangère à l'utilisateur dans l'adresse de la relation.

Si l'on suppose que chaque utilisateur a une ou plusieurs adresses, numéro de téléphone, etc., vous pourriez avoir une table 'Users', une 'Table des Adresses" (contenant une clé primaire et puis non unique de référence pour les Utilisateurs), de même que pour les numéros de téléphone - ce qui permet à plusieurs lignes avec le même nom d'utilisateur de la clé étrangère, ce qui ferait de l'interrogation de 'toutes les adresses pour l'utilisateur X' assez simple.

Je n'ai pas de script, mais j'ai mySQL que vous pouvez utiliser.Avant que je mentionné qu'il semble y avoir deux logiques d'approches pour ranger cartes de visite dans SQL:

  1. Stocker la totalité de la carte et de laisser la base de données de recherche (éventuellement) d'énormes chaînes de texte, et de les traiter dans une autre partie de votre code, ou même du côté client.par exemple

    CREATE TABLE IF NOT EXISTS vcards (
    name_or_letter varchar(250) not NULL,
    vcard le texte n'est PAS NULL,
    timestamp horodatage par défaut CURRENT_TIMESTAMP sur la mise à jour CURRENT_TIMESTAMP,
    CLÉ PRIMAIRE (username)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Probablement facile à mettre en œuvre, (en fonction de ce que vous faites avec les données) si vos recherches sont va être lent si vous avez de nombreuses entrées.Si c'est juste pour vous, alors cela pourrait fonctionner, (si c'est une bonne qualité, alors il est jamais juste pour vous.) Vous pouvez ensuite traiter les vCard côté client ou côté serveur à l'aide de quelques belles module que vous partagez, (ou quelqu'un d'autre a partagé avec vous.)

J'ai regardé vCard évoluer et savoir qu'il va être un peu de changement au /votre/ de temps dans le futur, donc j'utilise trois tables.

La première est la carte, (la plupart du temps des liens de retour à ma table existante si vous n'avez pas besoin de ce alors la vôtre peut être une version réduite).Le deuxième est la carte de définitions, (qui semblent être appelé profil en vCard parler).La dernière est tout le réel de données pour les cartes.

Parce que j'ai laissé DBIx::Class, (oui je suis un de ceux) faire tout le travail de base de données cette, (trois tableaux) semble fonctionner assez bien pour moi, (bien évidemment, vous pouvez serrer les types de match rfc2426 de plus près, mais pour la plupart, chaque élément de données est simplement une chaîne de texte.)

La raison que je n'ai pas de normaliser l'adresse de la personne, c'est que j'ai déjà un l'adresse de la table dans ma base de données et ces trois ne sont que pour les non-utilisateurs des détails de contact.

 CREATE TABLE `vCards` (   
 `card_id` int(255) unsigned NOT NULL AUTO_INCREMENT,   
 `card_peid` int(255) DEFAULT NULL COMMENT 'link back to user table',   
 `card_acid` int(255) DEFAULT NULL COMMENT 'link back to account table',      
 `card_language` varchar(5) DEFAULT NULL COMMENT 'en en_GB',
 `card_encoding` varchar(32) DEFAULT 'UTF-8' COMMENT 'why use anything else?',
 `card_created` datetime NOT NULL,  
 `card_updated` datetime NOT NULL,
 PRIMARY KEY (`card_id`) )
 ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='These are the contact cards'

   create table vCard_profile (
    vcprofile_id int(255) unsigned auto_increment NOT NULL,
    vcprofile_version enum('rfc2426') DEFAULT "rfc2426" COMMENT "defaults to vCard 3.0",
    vcprofile_feature char(16) COMMENT "FN to CATEGORIES",
    vcprofile_type enum('text','bin') DEFAULT "text" COMMENT "if it is too large for vcd_value then user vcd_bin",
  PRIMARY KEY (`vcprofile_id`)
) COMMENT "These are the valid types of card entry";
INSERT INTO vCard_profile VALUES('','rfc2426','FN','text'),('','rfc2426','N','text'),('','rfc2426','NICKNAME','text'),('','rfc2426','PHOTO','bin'),('','rfc2426','BDAY','text'),('','rfc2426','ADR','text'),('','rfc2426','LABEL','text'),('','rfc2426','TEL','text'),('','rfc2426','EMAIL','text'),('','rfc2426','MAILER','text'),('','rfc2426','TZ','text'),('','rfc2426','GEO','text'),('','rfc2426','TITLE','text'),('','rfc2426','ROLE','text'),('','rfc2426','LOGO','bin'),('','rfc2426','AGENT','text'),('','rfc2426','ORG','text'),('','rfc2426','CATEGORIES','text'),('','rfc2426','NOTE','text'),('','rfc2426','PRODID','text'),('','rfc2426','REV','text'),('','rfc2426','SORT-STRING','text'),('','rfc2426','SOUND','bin'),('','rfc2426','UID','text'),('','rfc2426','URL','text'),('','rfc2426','VERSION','text'),('','rfc2426','CLASS','text'),('','rfc2426','KEY','bin');

create table vCard_data (
    vcd_id int(255) unsigned auto_increment NOT NULL,
    vcd_card_id int(255) NOT NULL,
    vcd_profile_id int(255) NOT NULL,
    vcd_prof_detail varchar(255) COMMENT "work,home,preferred,order for e.g. multiple email addresses",
    vcd_value varchar(255),
    vcd_bin blob COMMENT "for when varchar(255) is too small",
    PRIMARY KEY (`vcd_id`)
) COMMENT "The actual vCard data";

Ce n'est pas le meilleur SQL, mais j'espère que ça aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top