Супертип / Подтип, выбирающий категорию: полное непересекающееся или неполное перекрытие

11

Я создаю базу данных инвентаризации, которая хранит ИТ-оборудование, такое как настольные компьютеры, ноутбуки, коммутаторы, маршрутизаторы, мобильные телефоны и т. Д. Я использую шаблон супертипа / подтипа, где все устройства хранятся в одной таблице, и конкретную информацию помещается в таблицы подтипов. Моя дилемма заключается в выборе между двумя вариантами:

введите описание изображения здесь

На верхней диаграмме все устройства имеют общие подтипы. Например, настольные компьютеры и ноутбуки могут иметь записи в следующих таблицах: Device, NetworkDevice. Коммутатор будет иметь записи в: Device, NetworkDevice. Маршрутизатор будет иметь записи в: Device, NetworkDevice, WANDevice. Любое устройство, для которого мы отслеживаем местоположение, будет иметь запись в Location. Некоторые плюсы и минусы, которые я подумал для этой установки:

  • Pro: Выбор записей на основе общего поля, например, Hostname или LocationID, проще.
  • Pro: нет пустых полей.
  • Против: Таблицы, которые должны быть включены в операции CRUD для конкретного устройства, не очевидны и могут запутать будущих администраторов баз данных.

На нижней диаграмме все устройства имеют свой собственный подтип (есть другие классы устройств, которые здесь не показаны). В этой ситуации очевидно, в какие записи таблиц вставляются или из которых выбираются. Настольные компьютеры и ноутбуки идут в Компьютере и т. Д. Некоторые плюсы и минусы, которые я подумал для этой установки:

  • Pro: Сразу видно, какие таблицы использовать для операций CRUD для подтипов.
  • Pro: Нужно использовать только одну таблицу для операций CRUD.
  • Con: для выбора записей на основе общих полей подтипов необходимо объединить все таблицы, например, поиск по имени хоста или LocationID.

В обеих ситуациях поле ClassDiscriminator помещается в таблицы подтипов для использования с ограничением CHECK для управления тем, какие типы могут быть вставлены.

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

РЕДАКТИРОВАТЬ: конкретный вопрос, который я имею в связи с перекрывающейся природой таблицы «NetworkDevice». Эта таблица предназначена для хранения информации о сети для любого устройства с именем хоста и / или IP-адресом, будь то компьютер, коммутатор или маршрутизатор. Является ли пересекающаяся природа этой таблицы чем-то, что может вызвать проблемы, или это нормально, чтобы реализовать это таким образом?

Заранее спасибо за любой предоставленный вклад. Пожалуйста, спросите, нужна ли какая-либо дополнительная информация.

TheSecretSquad
источник
См dba.stackexchange.com/questions/15199/... на аналогичный вопрос , который ответил
Стивен Senkomago Musoke

Ответы:

15

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

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

  • Если общее количество полей базы данных в подтипах относительно невелико (скажем, менее 100) или существует значительная общность между подтипами, то разделение подтипов на отдельные физические таблицы, вероятно, не имеет большого значения. Это добавит значительные накладные расходы к отчетным запросам и поискам. В большинстве случаев лучше иметь одну таблицу и управлять своим подтипом в приложении. (Наверное, ближе всего к вашей проблеме)

  • Если ваш подтип очень непересекающийся, и разные подтипы имеют зависимые от типа структуры данных, висящие за ними (то есть дочерние таблицы или более сложные структуры), тогда таблицы подтипов имеют смысл. В этом случае каждый подтип, вероятно, имеет относительно небольшую общность в приложении (т. Е. В приложении имеется целая подсистема, выделенная для этого подтипа). Большинство отчетов и запросов, вероятно, будут происходить в рамках данного подтипа, при этом запросы кросс-типа в основном ограничены несколькими общими полями. (Система управления делами суда)

  • Если у вас есть большое количество подтипов с разнородными атрибутами и / или требованием сделать это настраиваемым, тогда более подходящей может быть общая структура и дополнительные метаданные. Посмотрите эту SO публикацию для краткого изложения некоторых возможных подходов. (Система администрирования страховых полисов)

  • Если у вас есть очень большое количество полей с небольшой общностью между вашими подтипами и небольшим требованием выполнять запросы к таблицам подтипов (то есть, ничего особенного в отношении многопоточных внешних объединений с вашими таблицами подтипов), тогда Таблицы типов могут помочь управлять разрастанием столбцов. (Патологически сложный вариант вашей проблемы)

  • Некоторые сопоставители O / R могут поддерживать только определенный подход к управлению подклассами.

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

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

ConcernedOfTunbridgeWells
источник
Спасибо за ваш подробный ответ. Изначально я хотел сохранить все в одной таблице, но некоторые поля для устройств не относятся к другим, и в итоге я получил бы кучу пустых полей. Например, все записи инвентаризации будут иметь поля для типа канала и поставщика услуг, которые являются специфическими для маршрутизаторов. Все записи также имеют поле номера телефона, которое не имеет смысла, если устройство не является телефоном. Любые предложения о том, как бороться с этим?
TheSecretSquad
2
@reallythecrash - накладные расходы для пустых полей составляют около одного байта на поле, поэтому с точки зрения использования ресурсов это намного меньше, чем объединение с таблицами подкласса. Действительно, единственным недостатком является то, что таблица будет выглядеть немного грязной с большим количеством нулей.
ConcernedOfTunbridgeWells
3
@reallythecrash - Если вы действительно хотите (и ваша СУБД поддерживает это - вы не указали, что вы используете), вы можете установить проверочные ограничения, основанные на дискриминаторе типов, которые устанавливают значение null / not-null в полях, соответствующих класс.
ConcernedOfTunbridgeWells
3

Сначала рассмотрим разработку надежной логической модели данных с использованием правил иерархии классификации моделирования данных, которые можно найти в книге Дэвида Хэя, посвященной шаблонам корпоративных моделей . При создании иерархии классификации каждое вхождение (строка) должно иметь один и только один подтип. Это означает, что подтипы являются взаимоисключающими. Классификация должна основываться на одной фундаментальной неизменной характеристике. Использование этого основного правила обеспечит большую ясность вашей модели. В модели, которую вы используете, единственной характеристикой, на которую следует классифицировать, является назначение устройства - телефон, сетевой коммутатор, компьютер, маршрутизатор и т. Д. Каждое устройство должно быть одного и только одного из этих типов. Так, например, местоположение не будет подтипом. Такие атрибуты, как IP-адрес, относятся к супертипу.

Я думаю, вы обнаружите, что количество типов устройств будет достаточно большим, чтобы гарантировать шаблон EAV, как упомянуто в другом ответе. Книга Дэвида Хэя, на которую я ссылаюсь, очень эффективно описывает эту модель. Однако, если число подтипов невелико, вы можете использовать практическое правило для принятия решения о реализации только таблицы супертипа со многими столбцами, допускающими обнуляемость, только таблиц подтипов с дублированными столбцами или обоих. Если каждый подтип сильно различается по своим атрибутам и не имеет связей на уровне супертипа, вы можете использовать только таблицы подтипов. Если обратное верно, вы можете использовать только таблицы супертипа. Если есть смесь, то реализуйте оба.

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

Тод эверетт
источник
Спасибо за информацию Тодд. Один из моих вопросов касается таблицы «Сетевое устройство». Эта таблица предназначена для хранения записей для любого устройства, которое имеет имя хоста и IP-адрес. Это означает, что все коммутаторы, компьютеры и маршрутизаторы хранят свои сетевые данные, хранящиеся в этой таблице. Из того, что я читал, это называется перекрывающимся подтипом, в котором таблица подтипов содержит связанные данные для более чем одного типа. Знаете ли вы, что этого следует избегать или я в порядке, если я так поступаю?
TheSecretSquad
Тодд, относительно твоего утверждения "создай слой абстракции представления, который представляет данные приложению ...". Это звучит как отличная идея. Я думал об использовании представлений точно так, как вы описали, но у меня возникли некоторые вопросы по этому поводу. Я знаю, что можно использовать представления для запроса и отображения данных в моем приложении, но является ли обычной практикой использование представлений для вставок и обновлений? Я знаю, что существуют некоторые ограничения на то, как ваши запросы должны быть структурированы (без упорядочения по пунктам и т. Д.) Для вставки / обновления с использованием представления. Если запрос структурирован правильно, целесообразно ли использовать представление для вставок и обновлений?
TheSecretSquad
По моему опыту, перекрывающиеся подтипы путают вещи на логическом уровне, поэтому я рекомендовал сначала вернуться к разработке полной логической модели. Вы можете использовать LDM для уточнения объема и понимания, прежде чем иметь дело с хранилищем. В представленной текущей модели существует некоторая путаница понимания между фундаментальной природой вещи - устройства - и тем, где это устройство живет в космосе. Уточнить это в LDM. Избегайте перекрывающегося подтипа в физической базе данных, если только вы не используете его для вертикального разделения столбцов, в этом случае он вообще не печатает.
Тодд Эверетт
Что касается уровня абстракции, вы можете использовать триггер «вместо», чтобы сделать вид доступным для обновления. Упомянутые вами ограничения (без упорядочения) являются ограничениями в самом представлении SQL, а не в его использовании. Для вставки / обновления нет заказа в любом случае. Другие варианты - написать модуль для обработки деталей вставки / обновления или написать хранимую процедуру для обработки. Я не вижу проблем с использованием любого из этих методов, так как производительность приемлема. Для записи синглтонного типа это должно быть хорошо. Массовые обновления могут быть проблемой.
Тодд Эверетт
2

Продукт не инвентарь. Инвентарь и продукты различны.

Продукт - это спецификация продукта, а не физическая вещь.

Физическая вещь - это Актив, который компания владеет (или хранит). У вас могут быть активы, которые вы отслеживаете по серийному номеру (дискретные активы), или активы, которые вы отслеживаете только по количеству (ресурсы инвентаря).

Я бы посмотрел книгу ресурсов Сильверстона по модели данных, том 1. У него есть хорошая схема для проектов, функций, цен, инвентаря. Это сэкономит вам много времени.

Нил Макгиган
источник
1
+1 очко за упоминание Книги Сильверстона по модели данных. Взглянул, и это было поучительно. С нетерпением жду, чтобы прочитать более подробно, как я думаю, любой, кто имеет вопросы моделирования данных, должен. Спасибо.
TheSecretSquad
0

Один из вопросов, который я хотел бы задать, - почему вы отслеживаете различные атрибуты предметов инвентаря? - Или, более конкретно, что вы делаете с этим атрибутом информации?

Если у вас много отчетов или форм, которые имеют конкретный смысл конкретных атрибутов, вам нужно использовать подход, рекомендованный ConcernedOfTunbridgeWell. Если, с другой стороны, эти атрибуты записываются с целью их перечисления или, возможно, сравнения их с аналогичными атрибутами схожих устройств, тогда у вас может быть (редкий) хороший повод использовать EAV. Я знаю, что «EAV - это чистое зло» по многим причинам, за исключением очень редких случаев, когда эти причины не имеют значения для конкретного приложения. У вас может быть такое приложение.

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

Джоэл Браун
источник
Спасибо за ваш вклад. Я рассматривал EAV, но думал, что смогу создать достаточно хорошую модель, не прибегая к сложностям, связанным с EAV.
TheSecretSquad