Схема БД адресной книги

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
4 460
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Я знаю о 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:

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

    СОЗДАТЬ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ 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, но я надеюсь, что это поможет.

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