Створення бази даних інвентаризації [закрито]


77

Це питання насправді не про "програмування" (не характерне для будь-якої мови чи бази даних), а більше про дизайн та архітектуру. Це також питання типу "Який найкращий спосіб зробити Х". Сподіваюся, це не викликає великих "релігійних" суперечок.

У минулому я розробляв системи, які так чи інакше ведуть певну форму інвентаризації предметів (не стосується яких предметів). Деякі використовують мови / БД, які не підтримують транзакції. У цих випадках я вирішив не зберігати кількість товару на руках у полі в записі товару. Замість цього кількість на руці розраховуються на загальну суму інвентаризації отримала - загальна кількість запасів продана. Це майже не призвело до розбіжностей в запасах через програмне забезпечення. Таблиці належним чином індексуються, а продуктивність хороша. Існує процес архівування на випадок, якщо кількість записів вплине на продуктивність.

Кілька років тому я почав працювати в цій компанії і успадкував систему відстеження запасів. Але кількість зберігається в полі. Коли запис реєструється, отримана кількість додається до поля кількості для товару. Коли товар продається, кількість віднімається. Це призвело до розбіжностей. На мою думку, це не правильний підхід, але попередні програмісти тут клянуться ним.

Я хотів би знати, чи існує консенсус щодо того, яким є правильний спосіб розробити таку систему. Також, які ресурси доступні, надруковані чи в Інтернеті, щоб отримати поради щодо цього.

Дякую


15
Коли ви говорите "попередні програмісти тут клянуться цим", ви маєте на увазі, що вони лаються кожен раз, коли їм доводиться над цим працювати?
MusiGenesis

Відповіді:


53

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

Якщо ви десь зберігаєте лише загальну кількість у полі, ви навіть не уявляєте, як ви дійшли до цього числа. Історія транзакцій відсутня, і у вас можуть виникнути проблеми.

Остання система, яку я написав, відстежує запас, зберігаючи кожну транзакцію як запис із позитивною чи негативною кількістю. Я виявив, що це працює дуже добре.


1
+1 У мене була та сама дилема, і я думаю, що зараз це найкращий вибір
INS

4
@Neil - чи можете ви прокоментувати ефективність цього підходу. здається, це пільговий підхід, але якщо у вас сотні продуктів і тисячі транзакцій, як і коли ви обчислюєте сукупні підсумки. або ви просто зберігаєте сукупний підсумок в іншому місці зі спокоєм, знаючи, що можете перерахувати за потреби?
Simon_Weaver

11
Я провів тест - опублікував близько 3 мільйонів записів (про позитивні та негативні коригування запасів) понад 2000 товарів. На підрахунок загальної суми всіх рядків, згрупованих за SKU, знадобилася лише частка секунди. Я повинен сказати, що я був абсолютно вражений тим, як швидко це спрацювало, і для проекту, який я роблю, я точно маю зростання на порядок, і мені не доведеться турбуватися про це найближчим часом. Очевидно, що якщо ви відображаєте підсумки запасів у реальному часі на веб-сайті, ви, мабуть, захочете їх кешувати, але навіть для всіх 2000 продуктів я можу майже миттєво розрахувати загальну суму.
Simon_Weaver

2
Банківські / бухгалтерські системи роблять щось подібне з операціями (дебетовими або кредитними) часто як окремі поля, але з однаковим ефектом підсумовування. В першу чергу з операційних причин створюється щомісячний баланс (зазвичай існує процес підтвердження місяця завершення), але це також метод, який дозволяє скласти 12 щомісячних дельта-чисел, щоб швидко скласти рік замість кожної транзакції протягом року . Якщо це робиться протягом багатьох років та мільйонів рахунків, вигода від продуктивності є реальною, а також дозволяє виправити кілька місяців тому, щоб вимагати лише перерахунку на кінець цього місяця.
ClearCrescendo

1
Ви повинні застосувати обидва, 1 поле - це кількість, і 1 таблиця для транзакції. Коли потрібно, поле кількості можна перерахувати. Вам потрібно це поле, оскільки продуктивність. Коли кінець місяця. нам слід перенести всі числа перед місяцем у новий місяць. Це моя ERP-система працює. і добре працює
Сірий Вовк

18

9

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


7

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

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

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

також зауважте, що якщо у вашій системі є розбіжності, то вона має помилки, які слід відстежувати та усувати

я працював із системами в обох напрямках, і обидва способи можуть працювати чудово - доки ви не ігноруєте помилки!


1
хм повернення не є справді винятковим, чи не так? якщо ви не продаєте чисто швидкопсувні предмети або щось інше, що неможливо перепродати
Simon_Weaver

2
@Simon: одна з ранніх систем інвентаризації, яку я написав, була для спеціального магазину морозива. Повернення було не тільки винятковим, їх було практично неможливим ;-)
Стівен А. Лоу,

5

Погляньте на модель даних ARTS (Асоціація стандартів роздрібних технологій) ( http://nrf-arts.org ). Він використовує таблицю StockLedger із записом кожного елемента, а зміни в інвентарі відстежуються в InventoryJournalEntries.


4

Важливо врахувати існуючу систему та вартість та ризик її зміни. Я працюю з базою даних, яка зберігає запаси, подібні до ваших, але вона включає цикли аудиту та зберігає коригування, як і квитанції. Здається, це працює добре, але всі залучені люди добре навчені, і співробітники складу не зовсім швидко вивчають нові процедури.

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

Якщо ви хочете побачити, як це робить великий додаток, подивіться на SugarCRM , у них є модуль управління запасами, хоча я не впевнений, як він зберігає дані.


4

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

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

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


3

Я б обрав перший шлях, де

обчислювана кількість розраховується на загальну суму отриманих запасів - загальну кількість проданих запасів

Правильний шлях, ІМО.

РЕДАГУВАТИ: Я також хотів би врахувати будь-які втрати запасів / збитки в системі, але я впевнений, що ви це покрили.


2

Я вже працював над системами, які вирішують цю проблему. Я думаю, що ідеальним рішенням є попередньо обчислена колонка, яка дає вам найкраще з обох світів. Ваша загальна сума буде десь полем, отже, немає дорогих пошуків, але вона не може вийти з синхронізації з рештою ваших даних (база даних підтримує цілісність). Я не пам’ятаю, які RDMS підтримують попередньо обчислені стовпці, але якщо у вас немає транзакцій, можливо, це теж буде недоступно.

Ви можете потенційно підробити попередньо обчислені стовпці (дуже ефективно ... я не бачу мінусів), використовуючи тригери. Вам, мабуть, знадобляться транзакції. IMHO, збереження цілісності даних, коли ви робите такий вид контрольованої денормалізації, є єдиним законним використанням тригера.


2

Інвентар Django спрямований більше на основні фонди, але може дати вам кілька ідей.

IE: ItemTemplate (клас) -> ItemsOnHand (екземпляр)

ItemsOnHand можна пов’язати з більшою кількістю ItemTemplates; Приклад Принтер і чорнильні картриджі потрібні. Це також дозволяє встановити точки упорядкування для кожного ItemOnHand.

Кожен ItemsOnHand пов’язаний з InventoryTransaction, що дозволяє легко проводити аудит. Щоб уникнути обчислення фактичних наявних позицій з тисячі запасів, використовуються контрольно-пропускні пункти, які є просто залишком + датою. Для обчислення предметів, що знаходяться під рукою, потрібно знайти найновіший контрольний пункт і почати додавати або зменшувати елементи, щоб знайти поточний баланс предметів. Періодично визначайте нові пункти пропуску.


1

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


0

Не маючи однієї чи двох колонок, я мав на увазі "загальний обсяг отриманих запасів - загальна кількість проданих запасів" приблизно такий:

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

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

Також я хотів зазначити, що, хоча це не "кодування", питання пов'язане з алгоритмами та дизайном, які IMHO є дуже важливими темами.

Дякуємо усім за ваші відповіді.

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


2
недоліком цього конкретного рішення є те, що продуктивність з часом погіршуватиметься та погіршуватиметься, оскільки вам доведеться нескінченно вести облік усіх отриманих або проданих товарних запасів, щоб отримати правильну поточну кількість!
Стівен А. Лоу

0

Ми вирішуємо різні проблеми, але наш підхід до деяких з них може бути вам цікавий.

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

Щоб застосувати це до інвентаризації, ви можете мати 3 поля:

inventory_received
inventory_sold
estimated_on_hand

Потім ви можете запустити процес (щодня?) За назвою:

SELECT * 
FROM   Inventory
WHERE  estimated_on_hand != inventory_received - inventory_sold

Звичайно, це покладається на користувачів, які переглядають це сповіщення та щось з цим роблять.

Крім того, у вас може бути функція скинути інвентаризацію деяким чином, або шляхом оновлення inventory_sold / получен, або, можливо, додавши інше поле "inventory_adjustment", яке може бути позитивним або негативним.

... лише деякі думки. Сподіваюся, це корисно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.