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





Я знаю о SQLite, но это не особо помогает - я говорю о том, чтобы найти лучшую схему (независимо от базы данных) для хранения этих данных.
Почему полная нормализация будет «беспорядком»? Это именно то, что делает нормализация менее беспорядочной.
Пер Джон, я не понимаю, в чем будет проблема с классической нормализованной схемой. Вы не дали много информации, чтобы продолжить, но вы говорите, что между пользователями и адресами существует связь «один-ко-многим», поэтому я бы предпочел стандартное решение с внешним ключом для пользователя в отношении адреса.
Если вы предполагаете, что у каждого пользователя есть один или несколько адресов, номер телефона и т. д., У вас может быть таблица «Пользователи», «Таблица адресов» (содержащая первичный ключ, а затем неуникальную ссылку на пользователей), то же самое для телефонные номера - позволяет использовать несколько строк с одним и тем же внешним ключом UserID, что упростит запрос «всех адресов для пользователя X».
Рассмотрим две таблицы для людей и их адресов:
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
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 адреса, несколько веб-сайтов и профилей обмена мгновенными сообщениями, все из которых я бы включил в свой контактный профиль. Если вы начинаете создавать систему управления контактами сейчас и не обременены архитектурными ограничениями (подумайте, что кантакты Gmail привязаны к одному адресу электронной почты), сделайте одолжение своим пользователям и сделайте свою структуру контактов такой же гибкой (нормализованной), как возможный.
Ура, -Д.
У меня нет сценария, но у меня есть mySQL, который вы можете использовать. Перед этим я должен упомянуть, что есть два логических подхода к хранению vCard в SQL:
Сохраните всю карту и позвольте базе данных искать (возможно) огромные текстовые строки и обрабатывать их в другой части вашего кода или даже на стороне клиента. например
СОЗДАТЬ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ vcards (name_or_letter varchar (250) NOT NULL, vcard текст НЕ NULL,
Отметка времени timestamp по умолчанию CURRENT_TIMESTAMP при обновлении CURRENT_TIMESTAMP,
ПЕРВИЧНЫЙ КЛЮЧ (username)
) ДВИГАТЕЛЬ = MyISAM ДИАГРАММА ПО УМОЛЧАНИЮ = 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, но я надеюсь, что это поможет.