Разработка базы данных инвентаризации [закрыто]

StackOverflow https://stackoverflow.com/questions/287097

  •  08-07-2019
  •  | 
  •  

Вопрос

На самом деле это вопрос не о "программировании" (не относится конкретно к какому-либо языку или базе данных), а скорее о дизайне и архитектуре.Это также вопрос типа "Какой наилучший способ сделать X".Надеюсь, это не вызовет особых "религиозных" споров.

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

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

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

Спасибо

Это было полезно?

Решение

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

Если вы сохраняете только общее количество в каком-то поле, вы понятия не имеете, как вы получили это число.Там нет истории транзакций, и у вас могут возникнуть проблемы.

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

Другие советы

Это зависит от того, что системы инвентаризации - это гораздо больше, чем просто подсчет товаров.Например, для целей бухгалтерского учета вам может потребоваться знать учетную стоимость запасов на основе модели FIFO (First-in-First-out).Это не может быть рассчитано по простой формуле "общее количество полученных запасов - общее количество проданных запасов".Но их модель может легко рассчитать это, потому что они изменяют учетную стоимость по мере продвижения.Я не хочу вдаваться в подробности, потому что это не проблема программирования, но если они клянутся в этом, возможно, вы не до конца поняли все их требования, которые они должны учитывать.

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

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

с другой стороны, если у вас большое количество товаров, несколько исключительных случаев и частый доступ, будет эффективнее поддерживать количество товаров

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

я создавал системы обоими способами, и оба способа могут работать просто отлично - до тех пор, пока вы не игнорируете ошибки!

Взгляните на модель данных ARTS (Association for Retail Technology Standards) (Ассоциация стандартов розничной торговли). (http://nrf-arts.org).Он использует таблицу StockLedger с записью каждого товара, и все изменения в инвентаре отслеживаются в InventoryJournalEntries.

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

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

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

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

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

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

Я бы выбрал первый способ, где

рассчитывается количество в наличии итого полученные запасы - итого проданные запасы

Правильный Путь, ИМО.

Редактировать: Я бы также хотел учесть любые потери / повреждения запасов в системе, но я уверен, что вы это предусмотрели.

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

Потенциально вы могли бы подделать предварительно вычисленные столбцы (очень эффективно...Я не вижу никаких недостатков) использование триггеров.Однако вам, вероятно, понадобятся транзакции.ИМХО, сохранение целостности данных, когда вы выполняете такого рода контролируемую денормализацию, является единственным законным использованием триггера.

Django-инвентарь ориентирован больше на основные средства, но может натолкнуть вас на некоторые идеи.

Т. Е.:ItemTemplate (класс) -> ItemsOnHand (экземпляр)

ItemsOnHand может быть связан с другими ItemTemplates;Требуется примерный принтер и чернильные картриджи.Это также позволяет устанавливать точки переупорядочения для каждого элемента вручную.

Каждый ItemsOnHand связан с InventoryTransactions, это упрощает аудит.Чтобы избежать расчета фактических позиций в наличии из тысяч постоянных транзакций, используются контрольные точки, которые представляют собой просто баланс + дату.Чтобы вычислить имеющиеся в наличии товары, выполните запрос, чтобы найти самую последнюю контрольную точку, и начните добавлять или вычитать товары, чтобы найти текущий баланс товаров.Периодически определяйте новые контрольные точки.

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

Если нет одного или двух столбцов, то то, что я имел в виду под "итогом полученных запасов - итогом проданных запасов", выглядит примерно так:

Select sum(quantity) as inventory_received from Inventory_entry
Select sum(quantity) as inventory_sold from Sales_items

тогда

Qunatity_on_hand = inventory_received - inventory_sold

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

Также я хотел бы упомянуть, что, хотя это не вопрос "кодирования", он связан с алгоритмами и дизайном, которые, ИМХО, являются очень важными темами.

Спасибо всем за ваши ответы на данный момент.

Нельсон Мармол

Мы решаем разные проблемы, но наш подход к некоторым из них может быть вам интересен.

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

Чтобы применить это к инвентарю, у вас может быть 3 поля:

inventory_received
inventory_sold
estimated_on_hand

Затем вы могли бы запускать процесс (ежедневно?) примерно так:

SELECT * 
FROM   Inventory
WHERE  estimated_on_hand != inventory_received - inventory_sold

Конечно, это зависит от того, что пользователи просматривают это предупреждение и что-то с ним делают.

Кроме того, у вас могла бы быть функция для сброса запасов каким-либо образом, либо путем обновления inventory_sold / received, либо, возможно, добавления другого поля "inventory_adjustment", которое может быть положительным или отрицательным.

...просто несколько мыслей.Надеюсь, это будет полезно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top