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