Пример разработки БД «Склад автозапчастей»

Почему склад? Потому, что эта задача прямо или косвенно связана с большим числом прикладных задач, в том числе просто с наведением порядка.

Почему автозапчастей? Потому, что данный вопрос косвенно понадобился лично мне и, что еще важнее, в нем все разбираются .

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

Назначение программы: оптимизация заполнения склада (избегания затоваривания и недостатка)

Основная цель: избежать затрат средств на приобретение невостребованных деталей, не создав задержек в ремонте из-за их отсутствия.

Дополнительные цели: помощь покупателям в подборе и приобретении запасных частей.

Основной объект: деталь, агрегат, запасная часть, артикул, единица хранения.

Задачи

  1. Исследовать систему складского хранения
  2. Создать, реорганизовать или использовать существующую единую структуру адресации мест хранения
  3. Анализ тенденций расходования запчастей
  4. Создать систему вероятностного расчета потребности в запасных частях
  5. Разработать интерфейс доступа к детализации складских запасов разным категориям потребителей.
Потребители
  1. Руководство
  2. Работники склада
  3. Планово-финансовый отдел
  4. Бухгалтерия
Аналогичные детали, имеющие разные артикулы Источники Документация и ее содержимое

Складское хранение

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

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

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

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

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

Итак, сразу можно подметить закономерность адреса хранения: помещение–стеллаж–ярус–секция. Одновременно возникает желание создать составное выражение, что сразу нарушит правила нормализации. Допустимо ли это?

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

Пусть номер места хранения будет выглядеть так: 1-301-Д-03-05.

Здесь 1 будет означать номер корпуса, 301 – номер комнаты, Д – стеллаж, 03 – уровень полки, 05 – секцию.

Что можно о нем сказать, какие выводы будут получены?

  1. Для хранения предусмотрено до 9 зданий. В случае расширения предприятия это может вызвать нехватку значений. Кроме того, нумерация информативна только если это реальные номера корпусов.
  2. Номер помещения скрывает в своей первой цифре этаж (вполне привычно) и таких этажей может быть также до 9, а комнат – до 99 на этаж. Кажется вполне достаточно.
  3. Если складские помещения будут представлять собой ангары (не редкость), то номер помещения вообще теряет смысл. Для единообразия его можно записывать, как 100 или 000.
  4. Для нумерации стеллажей используется одна русская буква, то есть их может быть в комнате до 33. Точнее 28, если мы уберем "неудобные" буквы (ЁЙЬЫЪ). Может и не хватить для большого помещения: потенциальная проблема.
  5. Двузначной нумерации уровней достаточно даже для очень высокого помещения с очень плоскими выдвижными полками.
  6. По всей вероятности то же самое можно сказать и о секции, но этот вопрос требует уточнения. Если в качестве такой единицы будет рассматриваться ящик, а стеллаж будет очень длинным... (Почти параноидальный, но объективный подход.)
  7. Оценка некоторой совокупности мест хранения Однако, если мы захотим произвести какие-либо действия с деталями, находящимися на определенном этаже, это потребует написания специальной подпрограммы.
  8. Необходимо введение нумерации мест, не вписывающихся в общую схему: холодильники, сейфовые шкафы и т.п. Их логично предсавить в виде шкафов.

Ни одно из перечисленных сомнений не должно остаться невыясненным (на самом деле их гораздо больше). Предположим, что все поставленные вопросы были решены положительно и номер остался именно в приведенном виде.

Для повторения и прикладного закрепления материала по количеству информации, давайте рассчитаем, сколько всего мест хранения можно закодировать таким образом. Для этого нам потребуется перемножить число вариантов для каждого фрагмента кода: 9*9*99*28*99*99 = 2 200 638 132 адресов. Естественно, что это никогда не будет целиком реализовано: смешно представить склад из 9 девятиэтажных зданий... Но то, что зданий может быть только 9, намного важнее общей суммы.

Всего мы видим 13 символов, но разделители (дефисы) можно не хранить, а подставлять программно, то есть останется 9 символов. Таким образом, для ассортимента в миллион наименований, размер поля для хранения кодов получится около 9 Мб. Но это не так. Ведь отдельные наименования могут храниться в 10 и более секциях, то есть в БД придется сделать не одно соответствие деталь–секция, а несколько. И это вполне естественно.

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

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

Вариант такого разложения приведен ниже с комментариями под каждой таблицей.

Складские здания
НаименованиеПоле  ПримечаниеКомментарий
bld_idС(1)Код зданияМы решили, что они будут с номерами от 1 до 9 и участвуют в составлении строки места хранения. Нет смысла делать числовой тип, чтобы не преобразовывать
bld_nameC(10)Название для выводаКратко, но так, чтобы его легко понял оператор при вводе
florsN(1)Число этажейФактически, нужно для ограничения при вводе
bld_noteM(10)Сюда можно вписать любые непредвиденные замечания
bld_squaN(7,1)Площадь в кв.мВеличина равна сумме площадей помещений, но, по сути, она является константой. Здесь мы сталкиваемся с денормализацией для ускорения работы с БД
bld_planM(10)Ссылка на графический файл с планом зданияЗаведомая ошибка!

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

Здесь сознательно опущен важный показатель высоты потолков, идентичный в рассуждениях с высотой полок. Попробуйте придумать решение самостоятельно.

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

Складские помещения
НаименованиеПоле  ПримечаниеКомментарий
room_idI(4)Код помещенияНомера в разных зданиях могут совпадать, нужен для удобства идентификации
bld_idС(1)Код привязки к зданию
room_noC(3)Номер комнатыСимвольный тип определяется использованием для сборки адреса хранения, ввод будет управляться программно
room_hN(4)Высота в мм
room_wN(5)Ширина
room_dN(5)Глубина
room_sqN(6,1)Площадь в кв.м
room_planM(10)Ссылка на графический файл с планом помещения
room_temp_idN(1)Ссылка на справочник управления климатом помещенияНаличие отопления, охлаждения и кондиционирования, хотя для большинства складов актуально лишь отопление

Здесь и далее размеры приведены в мм, что соответствует требованиям ЕСКД и реальной точности измерений. Площадь помещений не всегда равна произведению размеров (при непрямоугольной конфигурации).

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

Стеллажи
НаименованиеПоле  ПримечаниеКомментарий
rack_idI(4)Код стеллажа
rack_nameC(1)Название (буква)
room_idI(4)Код привязки к помещению
rack_wN(3)Ширина стеллажа по умолчанию

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

Уровни полок
НаименованиеПоле  ПримечаниеКомментарий
ShelfLev_idI(4)Код
ShelfLev_nomC(2)Номер уровня полки
rack_idI(4)Код привязки к стеллажу
shelf_hN(3)Высота полки в уровне по умолчанию
ShelfLev_hN(4)Высота уровня от пола в мм

Полки
НаименованиеПоле  ПримечаниеКомментарий
shelf_idI(4)Код полки
shelf_nomC(2)Номер полки
ShelfLev_idI(4)Код привязки к уровню полки
shelf_wN(4)ширина полки в ммРазмеры полки определяют возможные габариты хранения. См. также примечание к таблицы
shelf_hN(4)высота полки
shelf_dN(4)глубина полки
shelf_wtN(4)Допустимая нагрузка в кг
shelf_mater_idN(2)Ссылка на справочник материалов полок
shelf_hhN(4)Высота поверхности полки от пола в ммПараметр важен с точки зрения доступности работниками склада и механизмами. Он тоже равен сумме высот и толщин расположенных ниже полок, но является почти константой

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

Из перечисленной выше системы таблиц должен возникнуть закономерный вопрос: как сохранить информацию о месте хранения конкретного объекта? Для этого понадобится связывающая таблица.

Таблица связи объект—ячейка
НаименованиеПоле  ПримечаниеКомментарий
det_idI(4)Код детали
shelf_idI(4)Код полки

Таблица содержит всего два поля. Из них мы можем узнать (получить списки), на каких полках хранится определенный артикул и какие артикулы лежат на определенной полке.

А далее происходит связывание таблиц в обратном порядке и сборка полного адреса хранения. С учетом скорости работы реляционных таблиц, затрачиваемое на это время можно рассматривать как несущественное.

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

Таблица
НаименованиеПоле  ПримечаниеКомментарий
_idI(4)Код
_nameC()

Классификация запчастей

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

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

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

Для чего приведены эти рассуждения? Чтобы показать, что есть множество обстоятельств для описания конкретной модели детали, как пригодной для различных автомобилей. Таким образом у этой детали в принципе не может быть свойства "автомобиль назначения": их много. Отсюда вытекает неизбежная необходимость создания таблицы, связывающей детали и модели автомобилей. Она будет содержать одну или несколько записей для каждой детали.

Таблица связи детали–модели
НаименованиеПоле  ПримечаниеКомментарий
det_idI(4)Код детали
model_idI(4)Код модели

В этом месте хочется подчеркнуть, что в своих рассуждениях мы пошли не сверху (от брендов) и не снизу (от конкретной детали), а как бы сбоку. Подобные рассуждения обязаны присутствовать при разработке баз данных. Простое линейное мышление неизбежно породит определенные "дыры" и ошибки.

Теперь можно порассуждать "сверху", от производителей и брендов. Информационная схема должна сойтись в сформированном узле.

Каждая деталь предназначена для определенного автомобиля (ранее такой тезис стал бы ошибкой). Последний представляет собой определенный бренд или марку (BMW, Opel...)

Таблица марок автомобилей
НаименованиеПоле  ПримечаниеКомментарий
brend_idI(1)Код маркиПредполагаем, что в обозримом будущем их число не превысит 256
brend_nameC(13)Самым длинным названием оказался Mercedes-Benz, что и определило длину поля
brend_siteM(10)На сайте можно получить всю необходимую информацию

Каждая марка может быть представлена множеством моделей.

Таблица моделей
НаименованиеПоле  ПримечаниеКомментарий
brend_idI(1)Код марки
model_idI(2)Код модели
model_nameC(30)Многие модели называются довольно длинно, например, у Bentley или Rolls-Royce, но нужно уточнение
model_ystartI(2)Год начала выпускаОбычно используется в каталогах
model_ystopI(2)Год окончания выпускаПоле может оказаться пустым, но оно несет информационный смысл для поиска (производима сейчас)

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

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

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

Еще одним важным моментом является уровень абстрагирования, который именно в этом месте начинает проваливаться у 80–90% учащихся. Дело в том, что существует объект как понятие и физический объект.

Возможно самым простым (и удобным для нас) разъяснением можно считать, что совокупность свойств мы используем для понятийного уровня. Каждый конкретный физический экземпляр объекта имеет этот набор свойств.

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

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

Но! Несложно вспомнить постоянно возникающее пролистование электронных перечней, крайне утомительное и, зачастую, беспесперктивное. Один из примеров – некоторые разделы Яндекс-маркета, не имеющие внутреннего разбора товара. Как ни странно (2014 г.), раздел СУБД (8935 наименований) там устроен именно так: и листай их до посинения или думай, какие запросы задать, хотя изначальная рубрикация совершенно очевидна.

Здесь мы сталкиваемся с понятием рубрикации (аналогично предметному указателю для книг), которое позволяет находить и использовать информационные ресурсы более эффективно. Отюда же вытекает необходимость создания соответствующей рубрикационной таблицы. Разъяснения к ней см. здесь.

Таблица рубрик деталей
НаименованиеПоле  ПримечаниеКомментарий
rubr_idI(4)Код рубрики
rubr_nameC(??)Наименование рубрики
rubr_noteM(10)Примечание
rubr_parentI(4)Родительская рубрика

Поскольку каждую деталь кто-то произвел

Таблица производителей деталей
НаименованиеПоле  ПримечаниеКомментарий
vendor_idI(4)Код производителя
vendor_nameM(10)НазваниеЛучше сделать поле примечаний, так как проблема вывода на экран и поиска решаема достаточно просто
country_idI(1)Код страныОдного байта (256 значений) достаточно (193 страны) только с точки зрения того, что запчасти производятся далеко не везде
...Есть еще много-много интересных данных

И, наконец-то, вроде можно прийти к главной таблице (всего лишь описательной). Обратите внимание на то, как мы долго продирались именно к такой структуре.

Таблица деталей
НаименованиеПоле  ПримечаниеКомментарий
det_idI(4)Код
det_nameC(20)Краткое названиеУдобно использовать для основных видов работы на экране
det_name_fullM(10)Полное формальное наименованиеНапример, для документации
vendor_idI(4)Код производителя
det_noteM(10)

Данная таблица связана через таблицу "детали–модели" с марками и моделями, в которых детали можно использовать, а также понятно где и кем они произведены.

Однако найти детали по значимым свойствам (н-р, резьба, размер и т.д.) мы не сможем. Их нужно описывать дополнительно. Как и где? Это следующий серьезный "затык". Дело в том, что у всех начинающих сразу возникает желание либо натворить кучу таблиц, либо создать одну с несколькими сотнями в основном незаполненных полей. Естественно, что делать этого нельзя.

Зесь можно поступить довольно необычно, создав "странную" универсальную таблицу

Таблица характеристик деталей
НаименованиеПоле  ПримечаниеКомментарий
det_idI(4)Код детали
det_para_nameM(10)Название параметра
det_para_quaM(10)Условное количествоЗдесь могут храниться не только числа, а, например, название материала

Условным недостатком нашего варианта будет дублирование описаний одинаковых деталей от разных производителей, что решается дальнейшей нормализацией. (Опущено!)

Гораздо более существенно использование поля примечаний, по которому невозможно быстрое перемещение.

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

Таблица деталей
НаименованиеПоле  ПримечаниеКомментарий
_idI(4)Код
_nameC()

Таблица
НаименованиеПоле  ПримечаниеКомментарий
_idI(4)Код
_nameC()

Движение запчастей

Для простоты примем, что на склад поступили два наименования: 5 двигателей и 50 колесных дисков. Этот пример нужен, чтобы представить себе ввод информации с серийным номером и без, а также распределение по разным складским помещениям.

сканирование штрих-кодов мобильным терминалом сбора данных Чтобы осуществить сканирование, нам потребуется предварительно ввести в таблицу деталей значения штрих-кодов. Мобильность терминала сбора данных делает область его применения практически неограниченной: •проведение инвентаризации; •маркировка и перемаркировка товара; •приемка, подбор и отгрузка товара со склада; •уменьшение очередей (предварительное сканирование кодов с выбранных покупок и выпуск единой этикетки); •контроль производственного процесса.

НаименованиеПоле  ПримечаниеКомментарий
_idI(4)Код

НаименованиеПоле  ПримечаниеКомментарий
_idI(4)Код
_nameC()
take_dateD(8)

Справочники

систем (топливная, электрическая) агрегатов (двигатель, карбюратор, дверь в сборе) деталей Поставщики

Адреса. Использование системного ("правильного") ввода адресов для рассматриваемого случая кажется нецелесообразным. Это определяется сравнительно небольшим перечнем контрагентов. Адреса понадобятся для оформления документации и осуществления связи. Естественно, что в связи с неопределенностью длины поля, его тип будет задан, как Memo.

Таблицы БД

Основным объектом нашей информационной системы будет деталь. Соответственно, для их описания должна быть создана отдельная таблица.

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

НаименованиеПоле  ПримечаниеКомментарий
det_idI(4)Код детали
det_nameC(???)Наименование детали
det_manN()Код производителяНужен соответствующий справочник
det_N()
det_

Часть узлов будет иметь дополнительный параметр – серийный (индивидуальный) номер. В качестве примера можно привести двигатель.

Проводки внешние и внутренние Агрегаты agr_id agr_name agr_serno Детали dtl_id dtl_name dtl_serno agr_id Одним из важных аспектов обсуждения описания разнородных объектов является то, что у многих начинающих разработчиков возникает вполне естественное желание создать свою таблицу для каждого наименования. Принципиальных препятствий нет, так как количество обсуждаемых деталей достаточно конечно, а средствами СУБД создать новую таблицу несложно. Но, не следует забывать и об интеграции Параметры param_id param_ param_ Спр. параметров param_id param_name param_AD

Пользователи

Данная таблица играет достаточно большую роль, так как будет использоваться для разграничения доступа

См. здесь


Copyright © 1993–2020 Мацкявичюс Д.А. Все права защищены.
Никакая часть сайта не может быть воспроизведена никаким способом без письменного разрешения правообладателя и явной ссылки на данный ресурс.