2014-01-15 2 views
2

У меня очень простой вопрос относительно 2 альтернатив, из которых я не знаю, какой из них выбрать. У меня есть объекты, которые могут быть «контактами». «Контакт» может иметь несколько адресов электронной почты, несколько телефонных номеров и несколько адресов. В моей модели данных я свяжусь с сущностью, у которой есть 1 to n realtion для сущностей электронной почты, телефона и адреса. Теперь в электронной почте таблицы есть только поля «электронная почта» и «комментарии», а телефон имеет аналогичную структуру «phoneNumber» и «комментарии».Обзор базы данных с несколькими аналогичными объектами

enter image description here

ли это «лучше» держать тех, в 2-х различных таблиц, или я должен сделать одну таблицу, позволяет назвать его «деталь» или что-то, с колоннами «значение», «типа» и «комментарии» с типом, например 'email' или 'phoneNumber'.

enter image description here

Я использую L4 и с красноречивыми моделями я ожидал, что будет легко можно написать некоторые методы, которые дают мне такую ​​же функциональность, как с различными таблицами. Но я чувствую, что строки для разграничения между различными типами информации неверны. Чувствуется, что легче ошибиться. С нетерпеливой загрузкой я ожидаю, что у меня не будет значительно больше запросов, даже если у меня есть 2 таблицы. FYI количество строк в телефоне/электронной почте будет определенно ниже 10.000.

Имеет ли значение, какой тип я выбираю? Что бы вы сделали? И почему?

Спасибо за помощь,

С наилучшими пожеланиями

+0

Вы вошли во что-то религиозную войну. Способ понять проблему состоит в том, как данные будут использоваться. Вы всегда ищете «контакт» при соединении с другими таблицами? Или вы хотите связать конкретные типы контактов? –

+0

* Избранные объявления. * –

+0

"Better" - это субъективный термин. Как правило, вы торгуете уровнем нормализации для «простоты использования». У большинства людей есть служебный адрес, домашний адрес и три контактных номера: домашний, рабочий (прямой набор) и мобильный. Это «нормальный» (в отличие от «нормализованного»), чтобы хранить все это в одной таблице. – Strawberry

ответ

1

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

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

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

Но такие рассуждения можно принять до смешных крайностей. На самом деле вопрос не в том, разные ли вещи в реальном мире, но разные ли они для целей нашей системы. Например, я не могу себе представить, что, поскольку иногда адрес представляет собой почтовый ящик, а иногда это уличный адрес, а иногда это номер квартиры и т. Д., Мы должны иметь отдельные поля для каждой из этих вещей, а не просто «адресную строку 1 "и" адресная строка 2 ". Или что у нас должны быть отдельные поля для имени «коричневого человека» по сравнению с именем «блондинки», потому что они выглядят по-другому. У меня было много неприятных разговоров с пользователями, где я пытаюсь объяснить, что в отношении системы что все это «продукт», и пользователь говорит «нет», нет, как вы можете сказать, что мебель такая же, как и канцелярские принадлежности? Но если в системе мы записываем имя, количество на руках и цену , чем меня не интересует различие. Etc и т. д.

Действительно, некоторые из моих самых полезных моментов в разработке программного обеспечения были, когда я понял, что две вещи, которые различны в реальном мире, действительно одинаковы для системы и можно обрабатывать с одной таблицей или одним блоком кода вместо многих. Как и где-то вдоль линии, я выяснил, что у сотрудников, поставщиков и клиентов есть имена, адреса, номера телефонов, d электронной почты. Поэтому теперь вместо того, чтобы иметь все эти поля в таблице employee и все те же поля в таблице поставщиков и все те же поля снова в таблице клиентов, я создаю одно поле, которое я называю «человеком», и помещаю туда все обычные вещи , а затем просто ссылку на него из других таблиц. Поэтому, когда кто-то приходит и говорит, что теперь мы должны обрабатывать иностранные адреса, я меняю одну таблицу вместо трех, и если бы я был умным, то вместо функции адреса был форматирование, а не 3.

В этом случае, что вы собираетесь делать делать с телефонными номерами и адресами электронной почты? Вероятно, в большинстве случаев пользователи могут вводить их, а затем показывать их.Я могу легко представить себе систему, в которой вы даже не сможете проверить, что это такое. Во время ввода данных имеется выпадающее меню для «типа контактной информации», и во время отображения вы показываете тип контакта вместе с контактным значением, вероятно, отсортированным по типу контакта. Если вы отправляете автоматические электронные письма, возможно, вы выберите, где type = 'email'.

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

BTW, если вы используете одну таблицу, вам нужен код, чтобы сказать, какой тип контакта это. Я думаю, вы это понимаете. Я предлагаю вам рассмотреть возможность создания справочной таблицы, содержащей коды и их определения, например, создать таблицу contact_type (contact_type_code char (2) первичный ключ, contact_type_description varchar (40)), а не жестко кодировать типы контактов в программе. Или, что еще хуже, укажите описание типа контакта в каждой записи, поэтому иногда он говорит «электронная почта», а иногда «электронная почта» и другие «электронная почта» и, возможно, в других случаях «e-male» или «internet», ,

Извините за длинный бессвязный ответ.

+0

Спасибо за этот совет. Мое приложение довольно мало, но требования смутно объясняются и, похоже, изменяются у клиентов. Я думаю, что один стол легче поддерживать –

0

Это, как я обычно дизайн таблицы для адресов, контактов и электронной почты:

Пример типов адресов может быть «Главная», «Почтовый» , «Работа» и т.д.

address_types 
    id     varchar(15)(P) 

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

addresses 
    id     unsigned int(P) 
    address_type_id  varchar(15)(F address_types.id) 
    line1    varchar(50) 
    line2    varchar(50) 
    city_id    unsigned int(F cities.id) Default NULL 
    county_id   unsigned int(F counties.id) Default NULL 
    zip     varchar(6) 
    zip4    char(4) Default NULL 
    lat     decimal(10,8) // Provides for accuracy to ~1mm. Default to NULL  lon      decimal(11,8) // Provides for accuracy to ~1mm. Default to NULL 

Вы можете или не хотите, такие вещи, как fips_number и столбцы, перечисленные после нее. Это коды, которые использовались правительством США.

cities 
    id      unsigned int(P) 
    state_id    unsigned int(F states.id) 
    name     varchar(50) 
    lat      decimal(10,8) // Provides for accuracy to ~1mm. Default to NULL 
    lon      decimal(11,8) // Provides for accuracy to ~1mm. Default to NULL 
    fips_number    unsigned int // Default NULL 
    census_code    unsigned int // Default NULL 
    census_class_code  char(2) // Default NULL 
    gsa_code    unsigned int // Default NULL 
    opm_code    unsigned int // Default NULL 

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

cities_counties 
    city_id    unsigned int \_ (P) (F cities.id) 
    county_id   unsigned int/ (F counties.id) 

типы Пример контакта может быть «Главная», «Работа», «пейджера», «Клетка» и т.д.

contact_types 
    id     varchar(15)(P) 

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

contacts 
    id     unsigned int(P) 
    contact_type_id  varchar(15)(F contact_types.id) 
    country_code  char(3) // Default to NULL 
    area_code   char(3) 
    exchange   char(3) 
    station    char(4) 
    extension   varchar(10) // Default to NULL 

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

counties 
    id      unsigned int(P) 
    state_id    unsigned int(F states.id) 
    name     varchar(50) 
    fips_number    unsigned int // Default NULL 

Посмотрите на ISO 3166-1 для получения дополнительной информации о кодах стран.

countries 
    id      char(2)(P) 
    iso3     char(3)(U) 
    iso_num     char(3)(U) 
    name     varchar(44)(U) 

Пример контакта типа может быть «Главная», «Работа» и т.д.

адреса
email_types 
    id     varchar(15)(P) 

электронной почты - вы можете или не хотите, чтобы разделить их, как в моем примере.

emails 
    id    unsigned int(P) 
    email_type_id varchar(15) 
    mailbox   varchar(255) 
    domain   varchar(255) 

Посмотрите на ISO 3166-2 для получения дополнительной информации о государственных кодах.

states 
    id      unsigned int(P) 
    country_id    char(2)(F countries.id) 
    code     varchar(3) 
    name     varchar(45) 
    fips_number    unsigned int // Default NULL 

И тогда, конечно, вы связываете их к объекту:

customer_addresses 
    id    unsigned int(P) 
    customer_id  unsigned int(F customers.id) 
    address_id  unsigned int(F addresses.id) 

customer_contacts 
    id    unsigned int(P) 
    customer_id  unsigned int(F customers.id) 
    contact_id  unsigned int(F contacts.id) 

customer_emails 
    id    unsigned int(P) 
    customer_id  unsigned int(F customers.id) 
    email_id  unsigned int(F emails.id) 
+0

Это намного сложнее, чем большинство систем, над которыми я работал. Например, когда мне все равно, в какой уезде город? Или что такое «код переписи» для города? Если вы занимаетесь судоходством или занимаетесь демографическими исследованиями, возможно, это все ценно, и в этом случае, прохладно. Но для большинства систем это намного проще, например, текстовое поле свободной формы для названия города. Построение такого рода сложности, если вам это не нужно, просто приводит к неприятностям, когда вы попадаете в случаи, которые не подходят для формы. Подобно неамериканским номерам телефонов не всегда разбиваются на группы из 3, 3 и 4 цифр. – Jay

+0

@Jay - на самом деле, этот дизайн исходит из расходов более 15 лет в судоходстве. Все номера телефонов в Северной Америке соответствуют шаблону 999-999-9999, как и все почтовые индексы - 5 цифр (США и MX) или 6 символов (CA). Ответ, хотя, как и многие ответы, относящиеся к дизайну базы данных, действительно означает отправную точку. Мы понятия не имеем, что такое бизнес компании Matthias, лучшее, что мы можем сделать, это дать ему несколько советов. –

+0

Примечание. Я сказал: «Если вы находитесь в судоходном бизнесе ...». Так что для вас этот дизайн вполне может иметь большой смысл. Но для большинства систем много ненужной сложности. И да, все номера телефонов в Северной Америке 999-999-9999, но номера телефонов на других континентах - нет. Я не пытался сказать, что ваш дизайн глуп или что-то в этом роде, просто я думаю, что вы должны принять его в контексте, и вы должны понимать контекст. – Jay

Смежные вопросы