Я пытаюсь создать реляционную базу данных в Access 2016, чтобы вести инвентаризацию предметов, хранящихся в нашем офисе. Большинство из них находятся в каких-то коробках, поэтому я решил, что каждая запись должна быть Container
, которая может быть либо коробкой, сумкой или физическим контейнером, содержащим несколько предметов, либо это может быть просто один не содержащийся предмет. Например, принтер, стоящий на полке, по-прежнему будет считаться Container
, но тип контейнера будет «Нет». В то время как коробка, полная безделушек, будет иметь тип «Коробка», и каждый из их предметов будет пронумерован в отдельной таблице.
Каждый Container
может иметь более одного Item
внутри - например. в коробке может быть пачка ручек, кабель HDMI и визитница. Все три предмета будут иметь свою собственную запись в таблице Item
с различными свойствами, описывающими предмет (марка, цвет, количество, если имеется более одного одинакового предмета и т. д.). Каждый Item
связан со своим Container
с помощью ContainerID
- связь одна -слишком много.
Проблема, которую я вижу в этом дизайне, заключается в избыточности данных - поскольку контейнер может быть как буквальным контейнером, так и просто одним элементом (например, принтером), в последнем случае мне пришлось бы назвать родителя Container
«Принтер», а также назвать ребенок Item
«Принтер». Или я мог бы оставить поле имени для Item
пустым, чтобы называлось только Container
, но я не уверен, считается ли это плохой практикой при проектировании баз данных.
Другая проблема заключается в том, что мой дизайн не позволяет аккуратно разместить подконтейнеры, например. если в большой коробке есть сумка, в которой есть и другие вещи, мне просто нужно указать описательный заголовок «Сумка с ручками, кабелями ...» Я не могу представить, что есть какой-либо способ сделать мою базу данных рекурсивной поэтому я не могу придумать никакого решения для этого. И, учитывая размер ящиков, с которыми я работаю, я часто сталкиваюсь с этим сценарием.
Итак, у меня два вопроса:
1) Есть ли обходной путь для решения, которое я пытаюсь реализовать, которое позволяет мне аккуратно хранить контейнеры внутри контейнеров?
2) Существует ли более эффективный дизайн базы данных для того, чего я пытаюсь достичь?
«Рекурсивность» — это свойство определений/алгоритмов/представлений, а не функций/отношений. Какие существуют варианты хранения иерархических данных в реляционной базе данных?Как создать иерархический рекурсивный запрос MySQL
Что такое «этот дизайн»? PS Очевидный дизайн, который, по-видимому, является вашим дизайном, таков: «элемент контейнера [c] содержит элемент [i]», «элемент [i] имеет описание [d]», «элемент [i] имеет свойство [p]». Насчет того, что «в моем дизайне нет подконтейнеров». Почему вы так думаете? Вы уже сказали: «Каждый элемент связан со своим контейнером с помощью ContainerID» и «контейнер может быть как буквальным контейнером, так и просто одним элементом». Таким образом, ваш дизайн «аккуратно вмещает подконтейнеры».
Что касается «хорошо» и «я не уверен, считается ли это плохой практикой при проектировании баз данных»: что мы отвечаем? Мы должны переписать учебник. Пришло время прочитать опубликованный академический учебник по информационному моделированию и проектированию баз данных. (Руководства по языкам и инструментам для записи и использования проектов не являются учебниками по информационному моделированию и проектированию баз данных.) PS «избыточность данных» (например, «эффективный», «хороший» и «плохой») не означает ничего конкретного и в любом случае только «плохая» «избыточность данных» не является «хорошей».
Ваш вопрос, безусловно, соответствует многим из доступных вариантов закрытого голосования, а также, вероятно, привлечет в первую очередь ответы, основанные на мнении, поскольку я уверен, что есть много способов подойти к этому... тем не менее, одним из возможных «рекурсивных» решение может быть следующий:
Создайте таблицу Items
, в которой каждая запись содержит уникальный идентификатор ItemID
в качестве первичного ключа и различные свойства элемента (например, описание, размер, цвет, значение, тип и т. д.), а также включает поле внешнего ключа с именем ContainerID
или Container
который может быть заполнен ItemID
другого элемента в самой таблице Items
:
В этом случае:
ContainerID
, представляя элементы, составляющие вашу безделушку, содержащиеся в одной коробке.ContainerID
относится к другому элементу в таблице Items
, контейнер также может иметь значение ContainerID
, что позволяет вам представлять бесконечный уровень вложенных контейнеров:Эта проблема очень похожа на проблему представления управленческой иерархии (или вообще любой иерархии), которая исследована и решена в этот вопрос.
Это действительно хорошая идея, спасибо! Я немного смущен тем, как это будет реализовано, хотя я думаю, что понимаю теорию - вы предполагаете, что каждый Item
имеет как свойство ContainerIDFK
, так и свойство ContainerID
, где первое относится к другому элементу ContainerID
, так что элементы существенно связаны друг с другом?
Не совсем — я говорю, что каждая запись в таблице Items
будет иметь уникальный ItemID
PK, а поле Container
будет содержать ItemID
другого элемента в таблице. Аналогично настройке, описанной в вопросе, указанном в моем ответе.
А, понятно, значит, для коробки, содержащей сумку с виджетом, у коробки есть запись в таблице Container
, у сумки есть запись в таблице Item
с ContainerID
коробки, а у виджета есть запись в таблице Item
. ContainerID
стол с Container
сумкой.
Я думаю, у вас есть это, но будет только таблица Items
без таблицы Container
- я добавил пример в свой ответ, чтобы помочь объяснить. Конечно, это всего лишь один из способов приблизиться к этому.
Пожалуйста, используйте текст, а не изображения/ссылки, для текста, включая таблицы и ERD. Перефразируйте или процитируйте другой текст. Используйте изображения только для того, что не может быть выражено в виде текста или для дополнения текста. Изображения нельзя искать или вырезать и вставлять.
Спасибо, @Lee Mac, теперь я с вами. Можно ли связать ContainerID с ItemID без VBA?
@Lou, да: вы можете использовать самообъединение в запросе - связанный ответ использует только VBA для построения SQL-запроса с достаточным количеством самообъединений для прохождения всех уровней иерархии.
Я отредактировал вопрос, пытаясь сделать его менее «слишком широким», я был бы признателен за предложения по дальнейшему улучшению вместо дальнейшего близкого голосования.