Frage

Ich muss Kontaktinformationen für Benutzer speichern.Ich möchte diese Daten auf der Seite als präsentieren hCard und herunterladbar als vCard.Ich möchte die Datenbank auch nach Telefonnummer, E-Mail usw. durchsuchen können.

Was ist Ihrer Meinung nach der beste Weg, diese Daten zu speichern?Da Benutzer mehrere Adressen usw. haben könnten, wäre eine vollständige Normalisierung ein Chaos.Ich denke darüber nach, XML zu verwenden, bin aber mit der Abfrage von XML-Datenbankfeldern nicht vertraut.Könnte ich weiterhin anhand der Kontaktinformationen nach Benutzern suchen?

Ich verwende SQL Server 2005, falls das wichtig ist.

War es hilfreich?

Lösung

Betrachten Sie zwei Tabellen für Personen und ihre Adressen:

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

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

Der Primärschlüssel (der jede einzelne Zeile eindeutig identifiziert) von Personen ist pid.Der PK von AddressBook ist die Zusammensetzung von PID und Tag (pid, tag).

Einige Beispieldaten:

Menschen

1, Kirk

2, Spock

Adressbuch

1, home, '123 Main Street', Iowa

1, work, 'USS Enterprise NCC-1701'

2, other, 'Mt. Selaya, Vulcan'

In diesem Beispiel hat Kirk zwei Adressen:ein „Zuhause“ und ein „Arbeitsplatz“.Einer dieser beiden kann (und sollte) als Fremdschlüssel (wie ein Querverweis) in vermerkt werden People in der Spalte „primaryAddressTag“.

Spock hat eine einzelne Adresse mit dem Tag „andere“.Da dies Spocks einzige Adresse ist, sollte der Wert „andere“ darin stehen primaryAddressTag Spalte für pid=2.

Dieses Schema hat den schönen Effekt, dass dieselbe Person daran gehindert wird, ihre eigenen Adressen durch versehentliche Wiederverwendung von Tags zu duplizieren, während gleichzeitig allen anderen Personen ermöglicht wird, beliebige Adress-Tags zu verwenden.

Darüber hinaus mit FK-Referenzen in primaryAddressTag, erzwingt das Datenbanksystem selbst die Gültigkeit des primären Adress-Tags (über etwas, das wir Datenbankfreaks als referenzielle Integrität bezeichnen), sodass sich Ihre – oder jede andere – Anwendung nicht darum kümmern muss.

Andere Tipps

Warum sollte eine vollständige Normalisierung „ein Chaos“ sein?Das ist genau die Art von Dingen, die durch die Normalisierung weniger chaotisch werden.

Haben Sie keine Angst vor der Normalisierung Ihrer Daten.Normalisierung, so John erwähnt, ist die Lösung, nicht das Problem.Wenn Sie versuchen, Ihre Daten zu denormalisieren, nur um ein paar Verknüpfungen zu vermeiden, werden Sie sich in Zukunft ernsthafte Probleme bereiten.Der Versuch, diese Art von Daten später umzugestalten, nachdem Sie über einen Datensatz mit angemessener Größe verfügen, wird keinen Spaß machen.

Ich empfehle Ihnen dringend, einen Blick darauf zu werfen Hochhaus aus 36 Signalen.Es wurde mir kürzlich empfohlen, als ich nach einem Online-Kontaktmanager suchte.Es macht so viel richtig.Mein einziger Einwand gegen den Dienst ist eigentlich, dass ich die kostenpflichtigen Versionen für zu teuer halte – das ist alles.

Aus heutiger Sicht passe ich nicht in ein flaches Adressprofil.Ich habe 4-5 E-Mail-Adressen, die ich regelmäßig nutze, 5 Telefonnummern, 3 Adressen, mehrere Websites und IM-Profile, die ich alle in mein Kontaktprofil aufnehmen würde.Wenn Sie jetzt mit dem Aufbau eines Kontaktverwaltungssystems beginnen und nicht durch architektonische Einschränkungen belastet sind (denken Sie an Gmail-Kontakte, die an eine einzige E-Mail-Adresse gebunden sind), dann tun Sie Ihren Benutzern einen Gefallen und gestalten Sie Ihre Kontaktstruktur so flexibel (normalisiert) wie möglich.

Prost, -D.

Ich kenne SQLite, aber das hilft nicht wirklich – ich spreche davon, das beste Schema (unabhängig von der Datenbank) zum Speichern dieser Daten herauszufinden.

Laut John sehe ich nicht, was das Problem mit einem klassischen normalisierten Schema wäre.Sie haben nicht viele Informationen gegeben, aber Sie sagen, dass zwischen Benutzern und Adressen eine Eins-zu-viele-Beziehung besteht, daher würde ich mich für eine Standardlösung mit einem Fremdschlüssel für den Benutzer in der Adressbeziehung entscheiden.

Wenn Sie davon ausgehen, dass jeder Benutzer eine oder mehrere Adressen, eine Telefonnummer usw. hat, könnten Sie eine „Benutzer“-Tabelle, eine „Adresstabelle“ (die einen Primärschlüssel und dann einen nicht eindeutigen Verweis auf Benutzer enthält) haben, das Gleiche für Telefonnummern – Ermöglicht mehrere Zeilen mit demselben UserID-Fremdschlüssel, was die Abfrage „aller Adressen für Benutzer X“ recht einfach machen würde.

Ich habe kein Skript, aber ich habe MySQL, das Sie verwenden können.Zuvor sollte ich erwähnen, dass es zwei logische Ansätze zum Speichern von vCards in SQL zu geben scheint:

  1. Speichern Sie die gesamte Karte und lassen Sie die Datenbank (möglicherweise) große Textzeichenfolgen durchsuchen und diese in einem anderen Teil Ihres Codes oder sogar auf der Clientseite verarbeiten.z.B.

    TABELLE ERSTELLEN, WENN NICHT EXISTIERT vcards (
    name_or_letter varchar(250) NICHT NULL,
    vcard Text NICHT NULL,
    timestamp Zeitstempel-Standardwert CURRENT_TIMESTAMP bei Aktualisierung CURRENT_TIMESTAMP,
    PRIMÄRSCHLÜSSEL (username)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Wahrscheinlich einfach zu implementieren (abhängig davon, was Sie mit den Daten machen), allerdings werden Ihre Suchvorgänge langsam sein, wenn Sie viele Einträge haben.Wenn das nur für Sie ist, könnte es funktionieren (wenn es gut ist, dann ist es das auch). niemals nur für Sie.) Sie können dann die vCard-Clientseite oder Serverseite mit einem schönen Modul verarbeiten, das Sie (oder eine andere Person, die es mit Ihnen geteilt hat) teilen.

Ich habe die Entwicklung von vCard beobachtet und wissen die es geben wird einige ändern sich zu /irgendwann/ in der Zukunft, also verwende ich drei Tabellen.

Die erste ist die Karte (diese verweist hauptsächlich auf meine vorhandenen Tabellen – wenn Sie diese nicht benötigen, kann es sich bei Ihrer Karte um eine gekürzte Version handeln).Das zweite sind die Kartendefinitionen (die im vCard-Sprachgebrauch anscheinend „Profil“ genannt werden).Das letzte sind alle tatsächlichen Daten für die Karten.

Weil ich DBIx::Class (ja, ich bin einer von denen) die gesamte Datenbankarbeit erledigen lasse, scheint dies (drei Tabellen) ziemlich gut für mich zu funktionieren, (obwohl Sie natürlich die Typen entsprechend straffen können rfc2426 genauer betrachtet, Aber in den meisten Fällen ist jedes Datenelement nur eine Textzeichenfolge.)

Der Grund, warum ich die Adresse der Person nicht normalisiere, ist, dass ich bereits eine Adresstabelle in meiner Datenbank und diese drei sind nur für Kontaktdaten von Nicht-Benutzern.

 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";

Das ist nicht das beste SQL, aber ich hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top