Проблема, связанная со схемой базы данных
У меня есть своего рода теоретический вопрос о базах данных. Чтобы сделать это более конкретным, я придумал пример.
Предположим, у меня есть магазин с продуктами. У меня много разных продуктов. Не каждый продукт имеет одинаковые применимые свойства. Например, я мог бы определить размер жесткого диска в гигабайтах, но не могу использовать это же свойство на процессоре, просто потому, что оно не применяется. Что мне нужно, так это база данных, где я могу динамически добавлять свойства к продуктам. Единственное, что я могу придумать, это следующее:
Одна таблица продуктов с идентификатором, именем и описанием.
Одна таблица свойств с идентификатором, Product_ID, свойством и значением.
Таким образом, я мог бы получить гигантскую, я полагаю, не очень эффективную, таблицу свойств. Это беспокоило меня долгое время. Кто-нибудь знает лучшее решение моей проблемы?
2 ответа
Это на самом деле движется к Шестой нормальной форме, просто такие люди, как вы, которые не имеют академического или эмпирического опыта, не знают (а) его название и (б) правила и предостережения. Такие люди реализовали то, что обычно называют Entity-Attribute-Value или EAV. Если это сделано правильно, это хорошо, и есть много тысяч медицинских систем, несущих диагностическую информацию и информацию о дозировке в таких таблицах. Если это не так, то это завтрак для одной собаки в использовании и обслуживании.
Сначала убедитесь, что у вас есть
Product
в истинном и полном 5NF.Всегда используйте полную декларативную ссылочную целостность;
CHECK
ограничения иRULES
,Никогда не кладите все это в один стол с
VARCHAR()
для значения. Всегда используйте правильные (применимые) типы данных. Это означает, что у вас будет несколько таблиц, по одной на каждый тип данных, и нет потери контроля или целостности.Точно так же любые ассоциативные таблицы (где есть множественная ссылка на другую таблицу [например, поставщик]) должны быть отдельными.
- Я предоставляю модель данных, которая имеет полный контроль над обсуждением; он включает в себя простой каталог, который может быть использован для проверки, а также навигации. Вы должны добавить каждый
CHECK
Ограничение иRULE
гарантировать, что данные и ссылочная целостность не будут потеряны. Это означает, например:- для
CPUSpeed
столбец, который хранится вProductDecimal
,CHECK
что он находится в надлежащем диапазоне значений - для каждого
Product
ТаблицаCHECK
что тип данных правильный дляProductType-ColumnNo
сочетание
- для
- Эта структура намного лучше, чем большинство EAV, и не совсем полный 6NF.
,
- Я предоставляю модель данных, которая имеет полный контроль над обсуждением; он включает в себя простой каталог, который может быть использован для проверки, а также навигации. Вы должны добавить каждый
Сохраните все обязательные столбцы в
Product
; использоватьsub-Product
таблицы только для необязательных столбцов.Для каждого такого (например,
Product
), вам необходимо создать представление (пунктирная линия), которое будет строить строки 5NF из таблиц EAV/6NF. У вас может быть несколько просмотров:Product_CPU
,Product_Disk
,Не обновлять через View. Сохраняйте все свои обновления в транзакционном режиме в сохраненном протоколе и вставляйте или обновляйте каждый из столбцов (т.е.
Product
а такжеsub-Product
таблицы, которые применимы, для каждого конкретногоProductType
) все вместе.Гигантский? Коммерческие базы данных (не бесплатные) не имеют проблем с большими таблицами или объединениями. На самом деле это очень эффективная структура, которая позволяет выполнять очень быстрый поиск, поскольку таблицы на самом деле ориентированы на столбцы (а не на строки). Если население гигантское, то оно гигантское, делайте свою арифметику.
Вам нужна еще одна таблица, таблица поиска для
Property
(или атрибут). Это является частью каталога и основано наProductType
Лучшее решение - перейти на полную, формальную шестую нормальную форму. Нет необходимости, если у вас есть только одна или несколько таблиц, для которых требуются необязательные столбцы.
Чтобы было ясно:
Шестая нормальная форма - строка состоит из первичного ключа и, самое большее, одного атрибута.
Это 6NF (по крайней мере для кластера таблиц продуктов), затем снова нормализуется (не в смысле обычной формы) с помощью DataType, чтобы уменьшить количество таблиц (в противном случае у вас будет одна таблица для каждого атрибута).
Это сохраняет полный контроль над Rdb (FK, ограничения и т. Д.); в то время как общие типы EAV не беспокоятся о DRI и контроле.
Это также имеет зачатки каталога.
Ссылка на модель данных кластера продуктов
Ссылка на нотацию IDEF1X для тех, кто не знаком со стандартом реляционного моделирования.
Обновить
Вы можете быть заинтересованы в этом ▶5NF 6NF Обсуждение ◀. Я напишу это в какой-то момент.
Первоначально я бы предложил вам иметь productproperty
таблица для моделирования отношений между продуктами и свойствами. Это позволит вам связать много продуктов с определенным свойством.
Тем не менее, я не заинтересован в идее сохранения значения рядом с каждым свойством как 1:1. Это может быть лучше, если у вас есть propertyvalue
таблица, которая связывает свойство со значением. Затем вы бросили бы productproperty
стол в пользу иметь богаче productpropertyvalue
таблица, которая может полностью описать отношения между продуктом, его свойствами и их значениями.
Возможно, тогда вы могли бы иметь следующее:
product => (ID (unique key), Name, Description)
property => (ID (unique key), Description)
propertyvalue => (ID (unique key), propertyID (foreign key), value)
productpropertyvalue => (ID (unique key), productID (foreign key), propertyValueID (foreign key))
Конечно, значения свойств могут быть сложными, а не простыми строками или целыми числами, но, надеюсь, это приведет вас в правильном направлении.