Как я могу решить эту проблему с обобщением? - PullRequest
3 голосов
/ 07 июня 2011

В нашей модели базы данных у нас есть Бенефициар сущность. Бенефициаром может быть физическое лицо или корпоративный бенефициар; физический бенефициар имеет ряд атрибутов, таких как имя, фамилия, пол и т. д .; кроме того, бенефициар (корпоративное или физическое лицо) может быть иностранцем или нет; это дополнительное различие переводит в разные значения домена для «общего» набора атрибутов (например, в Италии, где я живу, налоговые идентификаторы могут иметь формат данных, отличный от налоговых идентификаторов Великобритании).

Сейчас мы проводим реорганизацию нашей таблицы бенефициаров, поскольку разработчик, который первоначально работал над анализом и моделированием БД, сделал (IMO) недальновидный выбор. Он наложил ограничение первичного ключа на атрибут BeneficiaryName, который использовался для хранения либо корпоративного имени (например, «Microsoft Corporation») в случае корпоративного бенефициара, либо фамилии (например, Смита) для физического бенефициара. Таким образом, мы имеем (недопустимое) ограничение, что у нас не может быть более 1 бенефициара с фамилией «Смит» (или корпорация с именем «Смит») в нашей БД.

Мой подход к этому «перефакторингу» привел бы к обобщению для получателя; Я бы

  1. Очистить Таблица получателей, сохраняя только общие данные;
  2. Добавьте суррогатный первичный ключ в таблицу получателей, назовем его BeneficiaryID;
  3. Разделить Таблица получателей, с созданием двух дочерних объектов ( CorporateBeneficiary & PhysicalBeneficiary , различается флажком в основной таблице получателей), с 1 .. 1 связь с таблицей бенефициаров (внешний ключ будет ссылаться на идентификатор получателя)
  4. Поиск (значимых) первичных ключей для CorporateBeneficiary & PhysicalBeneficiary ;

Это должно решить вышеупомянутую проблему уникальности в BeneficiaryName. Кажется пока нормально?

Реальная проблема, с которой я столкнулся, заключается в следующем: как я могу / должен справиться с дальнейшим усложнением, добавленным атрибутом "foreign" в этой модели? Должен ли я оставить Foreign, как это, т. Е. Атрибут flag в Beneficiary? Если да, то как я могу удовлетворить потребность в различных атрибутах для концептуально схожей части информации (например, почтовый индекс, налоговый идентификатор) без дублирования атрибутов (zipcode_foreign, zipcode, taxid_foreign, taxid и т. Д.)? Стоит ли действительно стремиться разместить разные значения доменов в одном поле?

Любые предложения приветствуются ...

Ответы [ 4 ]

5 голосов
/ 07 июня 2011

"Очистить таблицу получателей, сохраняя только общие данные;"

Именно то, что нужно сделать.

"Добавить суррогатный первичный ключ в таблицу получателей, назовем его BeneficiaryID;"

Может быть полезно, но не забывайте, что ЕСЛИ существует «естественный» идентификатор, то его уникальность также должна быть обеспечена.

«Разделить таблицу получателей, создав две дочерние сущности(CorporateBeneficiary & PhysicalBeneficiary "

Да. Заметьте, что будет трудно обеспечить" абсолютную "целостность данных (при одновременном обеспечении того, что все NaturalBeneficiaries являются Бенефициарами, что все NonNaturalBeneficiaries также являются Бенефициарами, и что все Бенефициары являютсялибо естественные, либо ненатуральные бенефициары).

"различается по флагу в основной таблице бенефициаров"

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

"Найти (значимые) первичные ключи для CorporateBeneficiary & PhysicalBeneficiary;"

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

«Реальная проблема, с которой я столкнулся, заключается в следующем: как я могу / должен справиться с дополнительным усложнением, добавленным атрибутом« foreign »в этой модели?» «

Вы могли бы применять один и тот же подход, различая национальный и вненациональный (как для корпоративных, так и для физических лиц), и это может быть что угодно, от рекомендуемого до абсолютно необходимого, если целостность данных имеет ключевое значение, когда это касается, скажем, по крайней мере, национальные бенефициары. Например, может применяться законодательство, которое заставляет проверять, являются ли национальные номера SSN или идентификационные номера национальной корпорации «действительными» в соответствии с национальными правилами.Вероятно, крайне важно, чтобы такие правила проверялись в СУБД и , а не только в вашем приложении. Конечно, для неграждан подобные проверки обычно не требуются, или вообще невозможны.

Если вы возьмете такое различие между NПринимая во внимание то, что в вашей структуре базы данных учитываются национальные и не национальные, вы, скорее всего, также захотите создать представление, объединяющее два (национальные и не национальные) вместе, а затем вам придется «преобразовать» свои данные в«унифицированный» «общий» формат, который, вероятно, будет просто CHAR (даже если вы знаете, что, скажем, для National PhysicalBeneficiaries, содержимое будет номером их SSN, который, как вы знаете, состоит из некоторого фиксированного числа цифр).

Если вам не нужно учитывать в своей структуре базы данных такое различие между национальными и не национальными, то вы будете вынуждены использовать тот же «унифицированный» «общий» формат в вашей отдельной таблице, который будетхранение данных как для национальных, так и иностранных.

2 голосов
/ 07 июня 2011

Размещение разных значений домена в одном поле будет повторять тип проблемы, с которой вы сейчас сталкиваетесь, в основной таблице бенефициаров - в какой-то момент в будущем.Я бы применил этот подход:

Изменить предложенные ключи в таблице CorporateBeneficiary / PhysicalBeneficiary следующим образом:

  1. Добавить суррогатный первичный ключ, как вы предложили (BeneficiaryID)
  2. Используйте соответствующие механизмы базы данных или сайта для генерации BeneficiaryID как уникального сгенерированного значения.
  3. Сделайте первичный ключ CorporateBeneficiary (CB) и PhysicalBenificiary (PB) одинаковым - то есть BeneficiaryID.
  4. Makeпервичный ключ CB и PB - внешний ключ, ссылающийся на таблицу бенефициаров.

Затем для внешних деталей используйте аналогичный подход:

  1. Добавьте таблицу для страны с общимстолбцы, но ссылаются на соответствующий домен.
  2. Настройте новые таблицы аналогично CB / PB - то есть как отношения с таблицей получателя.

Затем создайте представления на основе левогоприсоединяется к созданию «виртуальных таблиц» - Бенефициар / ПБ / Зарубежные детали.Эти представления будут основой для доступа к информации.

Если у вас очень большие наборы данных (> 10 ^ 7 строк), вы можете обнаружить, что мой ответ на проблему проверки почтовыхкоды представляет интерес.Это очень длинный ответ;не просто;и это слишком много, если только объемы не слишком велики.

РЕДАКТИРОВАТЬ

Если ваши объемы данных меньше, подход, предложенный @James Anderson, из нескольких (например, для адреса) линии будут совершенно уместны.

1 голос
/ 07 июня 2011

Вы думаете по правильному принципу.

Я бы предложил вам иметь отдельную таблицу «адресов» для общего доступа всех бенефициаров.(Вы действительно описываете maildrop, который одинаков для людей и компаний!).Но самый простой способ справиться с проблемами i18n здесь - это сохранить его простым Line1, Line2, Line3, Line4 и кодом страны.

Я бы даже не пошел, имея конкретный почтовый индекс, так как они отличаются отпростые 4 цифры для британцев / [A-Z0-9] {2,4} [A-Z0-9] {2,4} / или даже для Ирландской Республики без каких-либо почтовых индексов (Официальное обоснование "Онам ничего такого не нужно, мы знаем, где вы живете. ")Кроме того, обычная позиция для почтового индекса варьируется от страны к стране (Великобритания в отдельной строке в конце, CH перед названием города и т. Д. И т. Д.), Некоторые домены следуют шаблону города, округа, штата, а другие места - нет.иметь штаты или округа или не использовать их в почтовых адресах.

0 голосов
/ 07 июня 2011

Для обобщения есть три понятия, как вы можете создать их для базы данных:

(объяснение 1 обобщения, 2 подтипа)


1.Одна таблица для всех

Здесь у вас есть все атрибуты из обобщения и подтипов в одной таблице.

Плюсы:

  • нет СОЕДИНЕНИЙ, не требуется СОЮЗ (= поэтому часто это самая быстрая возможность)
  • легко и быстро получить вещи из всего населения
  • легко и быстро вывести вещи из атрибутов обобщения
  • легко и быстро получитьвещи из атрибутов подтипов

Минусы:

  • редизайн таблицы при наличии новых подтипов с новыми атрибутами
  • много значений NULL длянеиспользуемые атрибуты
  • дополнительный атрибут для обозначения подтипа конкретной записи
  • (это выглядит как уродливый дизайн, но часто это невероятно, намного быстрее ...)

PKs / FKs: один PK, без FKs

Для вашего примера: только одна таблица для «Бенефициара».


2.Две таблицы

Только таблицы для подтипов.Нет таблицы для обобщения.

Плюсы:

  • очень простой и быстрый доступ ко всем данным один определенный подтип
  • легко добавить новыйатрибуты для определенного подтипа

Минусы:

  • трудно получить вещи из всего населения (UNION = медленно)
  • трудно добавить новые атрибуты в обобщение(все таблицы должны быть изменены)

PK / FK: каждая таблица имеет свой собственный PK, без FK

Для вашего примера: две таблицы для «CorporateBeneficiary» и «PhysicalBeneficiary»


3.Три таблицы

Имеют собственную таблицу для обобщения и для каждого подтипа.(Это то, что вы выбрали.)

Плюсы:

  • легкий доступ к атрибутам обобщения
  • легкий доступ к атрибутам подтипа
  • легко добавитьновые атрибуты

Минусы:

  • дорого для получения всех атрибутов целого объекта (JOIN = медленно)

PKs / FKs: в идеалеу вас есть одна последовательность ПК, используемая всеми таблицами.(т.е. Oracle Sequence) В таблицах подтипов pk-столбец является одновременно fk-столбцом таблицы обобщения.Это может быть немного сложно в СУБД, где у вас нет чего-то вроде Oracle Sequence.Там может быть необходимо иметь отдельные столбцы pk и fk в подтипах и собственную последовательность PK для каждой таблицы.(то есть, потому что sequence gen является свойством столбца)


Какой из них вы выберете, зависит от ваших требований.1.) и 3.) вы очень часто будете видеть, где случаи для 2.) очень редки, и многие разработчики не знают об этом проекте.

Лично, когда у меня нет других граничных условий, я выбираю 3потому что я считаю это самым чистым решением.Но я также выбрал вариант 1 в прошлом из-за соображений производительности.Не могу вспомнить, что я сделал что-то вроде варианта 2 со времен университета.: Р

...