Pregunta

Necesito almacenar información de contacto para los usuarios.Quiero presentar estos datos en la página como un Tarjeta h y descargable como tarjeta virtual.También me gustaría poder buscar en la base de datos por número de teléfono, correo electrónico, etc.

¿Cuál crees que es la mejor manera de almacenar estos datos?Dado que los usuarios podrían tener varias direcciones, etc., la normalización completa sería un desastre.Estoy pensando en usar XML, pero no estoy familiarizado con la consulta de campos de bases de datos XML.¿Aún podré buscar usuarios por información de contacto?

Estoy usando SQL Server 2005, si eso importa.

¿Fue útil?

Solución

Considere dos tablas para Personas y sus direcciones:

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

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

La clave principal (que identifica de forma única todas y cada una de las filas) de Personas es pid.La PK de AddressBook es la composición de pid y etiqueta. (pid, tag).

Algunos datos de ejemplo:

Gente

1, Kirk

2, Spock

Directorio

1, home, '123 Main Street', Iowa

1, work, 'USS Enterprise NCC-1701'

2, other, 'Mt. Selaya, Vulcan'

En este ejemplo, Kirk tiene dos direcciones:un 'hogar' y un 'trabajo'.Uno de esos dos puede (y debe) anotarse como una clave externa (como una referencia cruzada) en People en la columna PrimaryAddressTag.

Spock tiene una única dirección con la etiqueta "otro".Dado que esa es la única dirección de Spock, el valor "otro" debería ir en el primaryAddressTag columna para pid=2.

Este esquema tiene el agradable efecto de evitar que la misma persona duplique cualquiera de sus propias direcciones reutilizando etiquetas accidentalmente y al mismo tiempo permite que todas las demás personas usen las etiquetas de dirección que deseen.

Además, con referencias de FK en primaryAddressTag, el propio sistema de base de datos hará cumplir la validez de la etiqueta de dirección principal (a través de algo que los expertos en bases de datos llamamos integridad referencial) para que su aplicación (o cualquier otra) no tenga que preocuparse por ello.

Otros consejos

¿Por qué la normalización completa sería "un desastre"?Este es exactamente el tipo de cosas que la normalización hace menos complicadas.

No tengas miedo de normalizar tus datos.Normalización, como Juan menciona, es la solución, no el problema.Si intenta desnormalizar sus datos solo para evitar un par de uniones, se causará serios problemas en el futuro.Intentar refactorizar este tipo de datos en el futuro después de tener un conjunto de datos de tamaño razonable NO SERÁ DIVERTIDO.

Le recomiendo encarecidamente que consulte Alto de 36 Señales.Me lo recomendaron recientemente cuando buscaba un administrador de contactos en línea.Hace muchas cosas bien.En realidad, mi única objeción hasta ahora con el servicio es que creo que las versiones pagas son demasiado caras, eso es todo.

Tal como están las cosas hoy, no encajo en un perfil de dirección plano.Tengo entre 4 y 5 direcciones de correo electrónico que uso habitualmente, 5 números de teléfono, 3 direcciones, varios sitios web y perfiles de mensajería instantánea, todo lo cual incluiría en mi perfil de contacto.Si está comenzando a crear un sistema de administración de contactos ahora y no está limitado por las limitaciones arquitectónicas (piense en que los contactos de Gmail están vinculados a una sola dirección de correo electrónico), entonces haga un favor a sus usuarios y haga que su estructura de contactos sea lo más flexible (normalizada) posible. posible.

Saludos, -D.

Conozco SQLite, pero eso realmente no ayuda; estoy hablando de encontrar el mejor esquema (independientemente de la base de datos) para almacenar estos datos.

Según John, no veo cuál sería el problema con un esquema normalizado clásico.No ha proporcionado mucha información para continuar, pero dice que existe una relación de uno a muchos entre usuarios y direcciones, por lo que optaría por una solución estándar con una clave externa para el usuario en la relación de dirección.

Si asume que cada usuario tiene una o más direcciones, un número de teléfono, etc., podría tener una tabla de 'Usuarios', una 'Tabla de Direcciones' (que contiene una clave principal y luego una referencia no única a los Usuarios), lo mismo para números de teléfono: permite varias filas con la misma clave externa de ID de usuario, lo que haría que consultar "todas las direcciones del usuario X" fuera bastante simple.

No tengo un script, pero sí tengo MySQL que puedes usar.Antes de eso debo mencionar que parece haber dos enfoques lógicos para almacenar vCards en SQL:

  1. Almacene la tarjeta completa y deje que la base de datos busque (posiblemente) cadenas de texto enormes y procéselas en otra parte de su código o incluso en el lado del cliente.p.ej.

    CREAR TABLA SI NO EXISTE vcards (
    name_or_letter varchar(250) NO NULO,
    vcard texto NO NULO,
    timestamp marca de tiempo predeterminada CURRENT_TIMESTAMP en la actualización CURRENT_TIMESTAMP,
    CLAVE PRIMARIA (username)
    ) MOTOR = MyISAM CONJUNTO DE CARACTERES PREDETERMINADO = utf8 COLLATE = utf8_bin;

Probablemente sea fácil de implementar (dependiendo de lo que esté haciendo con los datos), aunque sus búsquedas serán lentas si tiene muchas entradas.Si esto es sólo para usted, entonces esto podría funcionar (si es bueno, entonces es nunca solo para usted.) Luego puede procesar el lado del cliente vCard o del lado del servidor usando algún módulo hermoso que usted comparta (o que alguien más haya compartido con usted).

He visto evolucionar vCard y saber Que habrá algún cambio en / algunos / tiempo en el futuro, así que uso tres tablas.

La primera es la tarjeta (en su mayoría enlaza con mis tablas existentes; si no la necesita, la suya puede ser una versión reducida).El segundo son las definiciones de tarjetas (que parecen llamarse perfil en vCard).El último son todos los datos reales de las tarjetas.

Porque dejé que dbix :: clase, (sí, soy uno de esos) hacer todo lo que la base de datos funciona esto, (tres tablas) parece funcionar bastante bien para mí (aunque obviamente puedes apretar los tipos para que coincidan rfc2426 Más de cerca, pero en su mayor parte cada pieza de datos es solo una cadena de texto).

La razón por la que no normalizo la dirección de la persona es que ya tengo una tabla de direcciones en mi base de datos y estos tres son solo para datos de contacto que no son usuarios.

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

Este no es el mejor SQL pero espero que ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top