Ответ 1
Андерс, не отказывайтесь от какой-либо целостности или твердости, например, типа безопасности.
(Приближение ответа).
@Anders. Нет, совсем нет, подтипирование - это хорошо (вопрос в том, какую форму вы используете, а какие - в преимуществах). Не отказывайтесь от какой-либо силы или целостности или типа безопасности или проверок или DRI. Выбранная форма потребует дополнительных проверок и, возможно, немного кода (зависит от вашей платформы).
Этот вопрос часто возникает, но искатель всегда имеет узкую перспективу; Я продолжаю делать одни и те же утверждения (подмножество) из неизменяемого набора. Идея состоит в том, чтобы оценить все варианты. Поэтому я пишу документ. К сожалению, это занимает больше времени. Возможно 4 страницы. Не готов к публикации. Но диаграммы закончены, я думаю, что вы на балу, и вы можете использовать его сразу.
Предупреждение: опытные инженеры по строительству проектов
Дорога не подходит для караванов или читателей с высоким коэффициентом Eek.
Ссылка на ▶ Четыре альтернативных модели данных ◀ в документе, находящемся в процессе разработки. Извинения за беспорядок на полу; Я скоро уберу.
▶ Ссылка на IDEF1X Notation ◀ для всех, кто не знаком со стандартом для моделирования реляционных баз данных.
-
Все они реляционные, с полной целостностью.
-
Параметры 6NF. Реляционная сегодня (SQL) не обеспечивает поддержку для 6NF; он не запрещает это, он просто не предоставляет структуры 5NF➔6NF. Поэтому вам нужно создать небольшой каталог, который некоторые называют "метаданные". Действительно, это просто расширение стандартного каталога SQL (таблицы sys). Требуемый уровень контроля моделируется в каждом варианте.
-
По существу EAV выполняется правильно, с полным контролем и целостностью (тип безопасности, декларативная ссылочная целостность и т.д.), а не как обычно.
Вам могут быть интересны эти связанные вопросы/ответы (в частности, посмотрите на Модели данных):
Несколько фиксированных и абстрактных гибких
Проблема с привязкой к схеме базы данных
"Простая" проблема с дизайном базы данных
Ответ на комментарии
... Таким образом, мы можем легко захватить строки "Комментарий", связанные с данным экземпляром специализированного типа. Это способ сделать это, или я буду сожалеть об этом решении позже? Есть ли какой-либо другой шаблон, который нам не хватает?
Не уверен, что вы имеете в виду. Комментарии, Заметки, Адреса, в конечном итоге используются (столбцы, резидентные) во многих таблицах, поэтому правильным способом является их нормализация; предоставить одну таблицу для комментариев; на который ссылается любая таблица, которая требует его. Вот общая таблица комментариев. Он используется в продукте (супертипе), потому что вы заявили какой-либо Продукт. Его можно так же легко использовать в некоторых подтипах Продукта, а не в других; в этом случае FK будет находиться в указанных подтипах продуктов.
Какова цель таблицы ProductType в примере вашего продукта 5NF/подтип? Он содержит строку, соответствующую каждому специализированному продукту, например, ProductCPU? Я предполагаю, что он указывает, какой специализацией является базовый продукт.
(Малая критическая ошибка на диаграмме, исправлена.)
Да, точно.
В стандартных терминах отношения (а не неконтролируемые беспорядки, передаваемые как базы данных), ProductType - это Дискриминатор; он определяет, какой из подтипов продукта применяется к этому продукту. Сообщает вам, с какой таблицей подтипа продукта вам нужно присоединиться. Пара вместе создает логический продукт. Не забудьте создать представления, по одному для каждого ProductType.
-
(Оцените, как изменяется ProductType, в точности, какую роль он играет, для каждой из четырех моделей данных.)
-
"Обобщение-специализация" - это все mumbo jumbo, OO-терминология; не пересекая линию и узнавая, что Реляционность способна на 30 лет. Если вы немного узнаете о Relational, у вас будет полная сила; в противном случае вы ограничены очень ограниченным подходом OO ко всему (у Амблера и Фаулера есть что ответить). Пожалуйста, прочитайте этот пост, от 11 декабря 10и далее. Модель реляционных баз данных Объекты, а не объекты; не классы.
Например, при добавлении нового продукта вы хотите указать, скажем, раскрывающийся список, какие типы продуктов можно добавить. Основываясь на этом выборе, можно определить, в какие таблицы помещать данные. Правильно? Мне жаль, что я говорю о коде приложения, но мне просто нужно поставить его в перспективе
Да. И на какой странице (с полями) предоставить следующую информацию, чтобы пользователь мог ввести данные.
Не стоит говорить о коде приложения, который будет использовать Rdb, они идут вместе, как муж и жена (а не муж и раб).
-
Для ваших классов OO сопоставьте дерево классов с Rdb, как только вы закончите моделирование Rdb, независимо от любого приложения, которое будет его использовать. А не наоборот. И не зависит от одного приложения.
-
Забудьте о "сохранении", у него много проблем ( "Потерянные обновления", "Повреждение целостности данных", "Проблематичная отладка", "Массовое разглашение" и т.д.). Все обновления для Rdb должны быть в транзакциях с соблюдением ACID, доступными в течение 30 лет, но Fowler и Ambler еще не читали об этом. Обычно это означает, что один хранимый proc pre xact.
Дискриминант является FK для таблицы типов, как мы установили ранее. Он обозначает, какой тип
spec.применяется к базовому типу. Но что содержит таблица дискриминантов?
Не ясно ли это из модели данных? ProducType CHAR(1)
или (2). Name Char(30)
.
Может быть удобным для отображения текстом, указывающим тип для целей пользовательского интерфейса,
Да, между прочим, например, контроль, противопоставление и т.д., устранение двусмысленности при кодировании или отчетности.
но также содержит точное имя таблицы, которое содержит специализированный тип?
Нет. Это было бы слишком физически, чтобы быть помещенным в данные. Запрещено по принципу.
Но это необязательно.
Скажите, что меня интересует Продукт с ID = 1. У него есть дискриминант, указывающий, что это ProductCPU. Как вы могли бы получить этот ProductCPU из вашего кода приложения?
Это будет легко, если вы возьмете предоставленную модель и внесете ее (все таблицы) в виде классов правильно и т.д. В запросе, который вы запрашиваете, не будет использоваться Views (для списков и более общего использования). Псевдокодом будет:
- с учетом
ProductId
(Подтип неизвестен, поэтому вы не должны сидеть в определенном подтипе окне), загрузите только супертипProduct
-
на основе Дискриминатора
Product.ProductType
, установить индикаторы и т.д. и загрузить применимый подтип, один изProductCPU; ProductMemory; ProductDisk; ProductTape
; и др. -
Я видел (и не согласен с) методы OO, которые загружают все подтипы для данного
ProductId
сразу: один подтип действителен; а остальные недействительны. Код по-прежнему должен ограничивать действительный класс дляProduct
на основеProduct.ProductType
.
Альтернативно, например. где контекст, пользователь сидит в определенном подтипом окне, например. ProductCPU
, с установленным классом и запросами ProductId
xxx. Затем используйте ProductCPU
Вид. Если он возвращает нулевые строки, он не существует.
- Может быть
ProductDisk
xxx, но неProductCPU
xxx. Как вы справляетесь с этим, указав ли вы, что есть Product`xxx, но он не является процессором или не зависит от требований приложения.
Для списков, где приложение заполняет сетку, независимо от ProductId
, используйте представления (по одному на каждый) для загрузки каждой сетки. Этот SQL основан на соединении и не требует ссылки на ProductType
.