Вопрос

Мне нужно хранить контактную информацию для пользователей. Я хочу представить эти данные на странице в виде hCard и загрузить в виде vCard . Я также хотел бы иметь возможность поиска в базе данных по номеру телефона, электронной почте и т. Д.

Какой способ хранения этих данных вы считаете лучшим? Поскольку пользователи могут иметь несколько адресов и т. Д., Полная нормализация была бы беспорядком. Я думаю об использовании XML, но я не знаком с запросами к полям XML db. Смогу ли я искать пользователей по контактной информации?

Я использую SQL Server 2005, если это имеет значение.

Это было полезно?

Решение

Рассмотрим две таблицы для людей и их адреса:

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

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

Первичным ключом (уникальным образом идентифицирующим каждую строку) People является pid . PK AddressBook представляет собой состав из pid и тега (pid, tag) .

Некоторые примеры данных:

Люди

1, Kirk

2, Spock

AddressBook

1, home, '123 Main Street', Iowa

1, work, 'USS Enterprise NCC-1701'

2, other, 'Mt. Selaya, Vulcan'

В этом примере у Кирка есть два адреса: один «домашний» и один «рабочий». Один из этих двух можно (и нужно) отметить как внешний ключ (например, перекрестную ссылку) в People в столбце primaryAddressTag.

Спок имеет один адрес с тегом «прочее». Поскольку это единственный адрес Спока, значение 'other' должно быть указано в столбце primaryAddressTag для pid = 2.

Эта схема имеет приятный эффект, заключающийся в том, что один и тот же человек не может дублировать свои собственные адреса путем случайного повторного использования тегов, в то же время позволяя всем другим людям использовать любые понравившиеся теги адресов.

Кроме того, с помощью ссылок FK в primaryAddressTag сама система баз данных будет обеспечивать валидность первичного тега адреса (с помощью чего-то, что мы, гики-базы данных, называем ссылочной целостностью), так что ваш - или любой - Приложение не должно беспокоиться об этом.

Другие советы

Почему полная нормализация "была бы беспорядком"? Это именно то, что нормализация делает менее грязным.

Не бойтесь нормализовать ваши данные. Нормализация, как Джон упоминает , является решением, а не проблемой. Если вы попытаетесь денормализовать ваши данные просто для того, чтобы избежать пары соединений, то в будущем у вас возникнут серьезные проблемы. Попытка провести рефакторинг данных такого рода после получения набора данных разумного размера НЕ БУДЕТ УДОВОЛЬСТВОВАТЬ.

Я настоятельно рекомендую вам проверить Highrise из 36 сигналов. Это было недавно рекомендовано мне, когда я искал менеджера контактов онлайн. Это так много правильно. На самом деле, мое единственное возражение по поводу сервиса в том, что я считаю, что платные версии слишком дороги - и все.

В нынешних условиях я не вписываюсь в плоский адресный профиль. У меня есть 4-5 адресов электронной почты, которые я использую регулярно, 5 телефонных номеров, 3 адреса, несколько веб-сайтов и профили IM, все из которых я бы включил в свой контактный профиль. Если вы начинаете создавать систему управления контактами сейчас и не обременены архитектурными ограничениями (представьте, что контакты gmail могут быть привязаны к одному адресу электронной почты), тогда сделайте одолжение своим пользователям и сделайте свою структуру контактов настолько гибкой (нормализованной), насколько это возможно. возможно.

Ура, -D.

Я знаю о SQLite, но это не очень помогает - я говорю о том, как определить лучшую схему (независимо от базы данных) для хранения этих данных.

Пер Джон, я не понимаю, в чем проблема классической нормализованной схемы. Вы не дали много информации для продолжения, но вы говорите, что между пользователями и адресами существует отношение один ко многим, поэтому я бы предпочел использовать стандартное болотное решение с внешним ключом для пользователя в отношении адресов.

Если вы предполагаете, что у каждого пользователя есть один или несколько адресов, номер телефона и т. д., у вас может быть таблица «Пользователи», «Таблица адресов» (содержащая первичный ключ и затем неуникальная ссылка на пользователей), то же самое для телефонных номеров - допускается наличие нескольких строк с одним и тем же внешним ключом UserID, что делает запрос «всех адресов для пользователя X» довольно простым.

У меня нет сценария, но у меня есть mySQL, который вы можете использовать. До этого я должен был упомянуть, что существуют два логических подхода к хранению vCards в SQL:

<Ол>
  • Сохраните всю карту и позвольте базе данных искать, (возможно) огромные текстовые строки, и обрабатывать их в другой части вашего кода или даже на стороне клиента. например

    СОЗДАЙТЕ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ vcards (
      name_or_letter varchar (250) NOT NULL,
     текст vcard NOT NULL,
      отметка времени отметка времени по умолчанию CURRENT_TIMESTAMP при обновлении CURRENT_TIMESTAMP,
     ПЕРВИЧНЫЙ КЛЮЧ ( имя пользователя )
    ) ENGINE = MySAM CHARSET ПО УМОЛЧАНИЮ = utf8 COLLATE = utf8_bin;

  • Вероятно, это легко реализовать (в зависимости от того, что вы делаете с данными), хотя ваш поиск будет медленным, если у вас много записей. Если это только для вас, то это может сработать (если это хорошо, тогда никогда только для вас.) Затем вы можете обработать клиентскую или серверную часть vCard, используя какой-то красивый модуль, который вы поделиться (или кто-то еще поделился с вами.)

    Я смотрел, как развивается vCard, и знаю, что некоторые изменится в будущем или в будущем, поэтому я использую три таблицы.

    Первая - это карта (в основном это ссылки на мои существующие таблицы - если вам это не нужно, то ваша версия может быть урезанной). Второе - это определения карт (которые в vCard говорят как профиль). Последний - это все фактические данные для карточек.

    Поскольку я позволил DBIx :: Class (да, я один из них), чтобы все базы данных работали так, (три таблицы), кажется, работают довольно хорошо для меня, (хотя, очевидно, вы можете ужесточить типы, чтобы более точно соответствовать rfc2426 , но по большей части каждый фрагмент данных представляет собой просто текстовую строку.)

    Причина, по которой я не нормализую адрес этого человека, состоит в том, что у меня уже есть таблица адресов в моей базе данных, и эти три только для не-контактных данных пользователя.

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

    Это не лучший SQL, но я надеюсь, что это поможет.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top