Проектирование базы данных, включая людей и организацию
Недавно я обнаружил метод подтипа / супертипа в проектировании реляционных баз данных и, следовательно, этот вопрос: является ли это правильный дизайн, смешанный с методом проектирования подтипа / супертипа?
Прежде чем я обратился persons
а также organisations
как два разных типа. Я понимаю, что это лучший способ иметь party
супертип people
а также organisation
, Теперь, когда это решено, добавив adresses
а также additional_addresses
оба применяются для organisations
а также для persons
тем самым соединяя их с супертипом parties
,
Кроме того, различные группы людей, которых я должен вести, например, employees
, projectcontacts
а также suppliercontacts
, Это все разные типы persons
в пределах party
, Это правильный способ присоединиться к столу с persons
для достижения этой цели? То же самое касается suppliers
а также debtors
, связанные с organisation
стол, так как supplier
а также debtors
всегда organisations
,
Я считаю, что это хороший способ проектирования, но я мог бы что-то упустить с первичными и внешними ключами, особенно когда смотрю на SupplierContacts
, Существует внешний ключ partyid
который должен относиться к person
а также внешний ключ supplierid
, но это supplierid
также относится к определенному partyid
в своей таблице. Не будет ли это нелепо тяжелой работой, чтобы иметь возможность запрашивать информацию из этой таблицы, и является ли этот дизайн даже правильным?
Моя главная проблема заключается в том, что многие таблицы должны ссылаться на человека или организацию, и вместо того, чтобы иметь два внешних ключа везде, оставляя один NULL всегда, так как я храню запись либо person
ИЛИ organisation
Теперь у меня есть только один внешний ключ: partyid
,
2 ответа
Ответ опирается на искусство проектирования первичных ключей.
Вы использовали суррогатный идентификатор в качестве первичного ключа для parties
таблица (одна из распространенных ловушек разработчиков), в то же время это не возможно обнаружить строку в parties
таблица на самом деле человек или организация без объединения с персонами или таблицами организации.
Поэтому, когда вы используете ПК parties
как FK в другой таблице, это не будет обнаружено, если сторона является желаемой, вы теряете бизнес-логику, побочный эффект использования суррогатного ключа.
Решение: Выберите натуральный ключ для стола для вечеринок.
Было бы рекомендовано иметь столбец дискриминатора в таблице сторон, называемый party_type
(перечисление, значения будут человек =1 и организация =2).
Первичный ключ таблицы сторон может быть {party_name + party_type}
,
В таблицах агрегации вроде SupplierContacts
наличие проверочного ограничения на {party_type = 1
} решит проблему.
Обратите внимание, что решение направлено на решение проблемы на уровне проектирования базы данных, в качестве альтернативы вы можете дополнительно работать на уровне своего приложения для архивирования целостности данных (менее рекомендуется, но в основном используется разработчиками!)
Мне не совсем понятен вопрос, который вы здесь задаете.
Я не знаю ни о каких механизмах баз данных, которые изначально поддерживают подтипы - они используются для концептуального моделирования, а в физическом дизайне они реализуются с тем, что будет поддерживать ядро базы данных.
Возможно, будет гораздо полезнее смоделировать это как физическую модель данных - потому что ваше решение о первичных и внешних ключах почти наверняка должно будет измениться в зависимости от того, каким образом вы физически представляете подтипы.
Существует несколько способов преобразования логического понятия "подтип" в физическую модель данных - 3 наиболее распространенных:
- таблица по подтипу. Это означает, что ваши внешние ключи могут нуждаться в ссылках на несколько таблиц (например, "персона" или "организация"), но ваши запросы / объединения просты.
- таблица супертипа с общими атрибутами, отдельные таблицы для данных подтипа (например, "вечеринка", "человек" и "организация") - в этом случае ваш внешний ключ переходит к "стороне", но для получения данных подтипа необходимо включить присоединиться к таблице подтипов. Это усложняет ваш SQL.
- общая таблица с множеством пропускаемых столбцов (например, "вечеринка" со всеми столбцами для человека и организации). Это делает внешний ключ простым, но опять же, ваша логика доступа к данным становится беспорядочной.
Чтобы помочь вам оценить дизайн, стоит разобраться с такими очевидными вопросами, как "какой номер телефона основного контакта поставщика х?", "Сколько людей работает над проектом у?" как запросы SQL и посмотрите, как ваша схема поддерживает это.