재고 데이터베이스 설계
이것은 "프로그래밍"(언어 나 데이터베이스에만 국한되지 않음)에 대한 질문이 아니라 디자인과 아키텍처에 대한 질문입니다. 또한 "X를 수행하는 가장 좋은 방법"유형의 질문이기도합니다. 나는 많은 "종교적"논쟁을 일으키지 않기를 바랍니다.
과거에 나는 어떤 식 으로든 어떤 형태의 품목 목록을 유지하는 시스템을 개발했습니다 (어떤 품목과 관련이 없는지). 일부는 트랜잭션을 지원하지 않는 언어 / DB를 사용합니다. 이러한 경우 에는 품목 레코드의 필드에 현재 고 품목 수량 을 저장하지 않기로 결정했습니다 . 대신 현재 고 수량 은 수령 한 재고의 합계-판매 된 재고의 합계로 계산됩니다. 이로 인해 소프트웨어로 인해 인벤토리의 불일치가 거의 발생하지 않았습니다. 테이블이 제대로 인덱싱되고 성능이 좋습니다. 레코드 양이 성능에 영향을 미치기 시작하는 경우 보관 프로세스가 있습니다.
이제 몇 년 전에이 회사에서 일하기 시작했고 재고를 추적하는 시스템을 물려 받았습니다. 그러나 수량은 필드에 저장됩니다. 항목이 등록되면받은 수량이 항목의 수량 필드에 추가됩니다. 품목이 판매되면 수량이 차감됩니다. 이로 인해 불일치가 발생했습니다. 제 생각에는 이것은 올바른 접근 방식이 아니지만 여기에있는 이전 프로그래머들은 그것을 맹세합니다.
그런 시스템을 설계하는 것이 옳은 방법이 무엇인지에 대한 합의가 있는지 알고 싶습니다. 또한 이에 대한 지침을 구하기 위해 사용할 수있는 자료, 인쇄 또는 온라인.
감사
나는 현재 회사에서 두 가지 접근 방식을 모두 보았고 확실히 첫 번째 (주식 거래를 기반으로 총계를 계산하는)쪽으로 기울일 것입니다.
어딘가에 필드에 총 수량 만 저장하는 경우 해당 숫자에 어떻게 도달했는지 알 수 없습니다. 거래 내역이 없으며 문제가 발생할 수 있습니다.
내가 작성한 마지막 시스템은 각 거래를 양수 또는 음수 수량의 레코드로 저장하여 재고를 추적합니다. 나는 그것이 매우 잘 작동한다는 것을 알았습니다.
- 데이터 모델 리소스 북, Vol. 1 : 모든 기업을위한 범용 데이터 모델 라이브러리
- 데이터 모델 리소스 북, Vol. 2 : 특정 산업을위한 데이터 모델 라이브러리
- 데이터 모델 리소스 북 : 데이터 모델링을위한 범용 패턴
나는 Vol 1과 Vol 2를 가지고 있으며 이것들은 과거에 꽤 도움이되었습니다.
재고 시스템은 단순히 항목을 계산하는 것 이상입니다. 예를 들어 회계 목적으로 FIFO (선입 선출) 모델을 기반으로 재고의 회계 가치를 알아야 할 수 있습니다. 단순한 "수령 재고 총계-판매 재고 총계"공식으로는 계산할 수 없습니다. 그러나 그들의 모델은 회계 가치를 변경하기 때문에 이것을 쉽게 계산할 수 있습니다. 이것은 프로그래밍 문제가 아니기 때문에 자세히 설명하고 싶지 않지만 그들이 그것을 맹세한다면 수용해야하는 모든 요구 사항을 완전히 이해하지 못했을 것입니다.
상황에 따라 둘 다 유효합니다. 전자는 다음 조건이 충족 될 때 가장 좋습니다.
- 합계 할 항목 수가 상대적으로 적습니다.
- 고려해야 할 예외 사례가 거의 또는 전혀 없습니다 (반품, 조정 등)
- 재고 품목 수량이 자주 필요하지 않습니다.
반면에 품목 수가 많고 예외적 인 경우가 많으며 자주 액세스하는 경우 품목 수량을 유지하는 것이 더 효율적입니다.
또한 시스템에 불일치 가있는 경우 추적하여 제거해야하는 버그 가 있습니다.
나는 두 가지 방법으로 시스템을 해왔고, 버그를 무시하지 않는 한 두 가지 방법 모두 잘 작동 할 수 있습니다!
ARTS (Association for Retail Technology Standards) 데이터 모델 ( http://nrf-arts.org )을 살펴보십시오 . 각 항목에 대한 레코드가있는 StockLedger 테이블을 사용하며 인벤토리 변경 사항은 모두 InventoryJournalEntries에서 추적됩니다.
기존 시스템과이를 변경하는 데 따른 비용 및 위험을 고려하는 것이 중요합니다. 나는 당신과 같은 종류의 재고를 저장하는 데이터베이스로 작업하지만, 여기에는 감사주기가 포함되고 영수증과 같이 조정 사항이 저장됩니다. 잘 작동하는 것 같지만 관련된 모든 사람이 잘 훈련되어 있고 창고 직원이 새로운 절차를 빨리 배우는 것은 아닙니다.
귀하의 경우 전체 db 구조를 변경하지 않고 조금 더 많은 추적을 찾고 있다면 추적 테이블 ( '트랜잭션'솔루션과 유사)을 추가 한 다음 재고 수준에 대한 변경 사항을 기록하는 것이 좋습니다. 재고 수준에 대한 대부분의 변경 사항을 업데이트하여 거래 기록도 남기는 것이 너무 어렵지 않아야합니다. 또한주기적인 작업을 추가하여 몇 시간마다 재고 수준을 트랜잭션 테이블에 백업하여 트랜잭션을 놓친 경우에도 변경이 발생한시기를 발견하거나 이전 상태로 롤백 할 수 있습니다.
대규모 응용 프로그램이 SugarCRM을 살펴보면 어떻게 데이터를 저장하는지 잘 모르겠지만 인벤토리 관리 모듈이 있습니다.
나는 이것이 실제로 총계가 필요할 때마다 (상대적으로) 값 비싼 카운트를 수행하는 것에 대한 일반적인 모범 사례 질문이라고 생각합니다. 무언가가 변경 될 때마다 카운트를 수행 한 다음 필드에 카운트를 저장하고 필요할 때마다 해당 필드를 읽습니다. 합계.
트랜잭션을 사용할 수 없으면 합계가 필요할 때마다 라이브 카운트를 사용합니다. 트랜잭션을 사용할 수있는 경우 동일한 트랜잭션 내에서 재고 업데이트 작업을 수행하고 재 계산 된 총계를 저장하는 것이 안전 할 것입니다. 이렇게하면 개수의 정확성이 보장됩니다 (여러 사용자에게 적용 할 수 있을지 확신 할 수는 없지만 데이터베이스 타격).
그러나 성능이 실제로 큰 문제가 아니라면 (최신 데이터베이스는 행을 계산하는 데 충분하므로 이것에 대해 거의 걱정하지 않을 것입니다) 매번 라이브 카운트를 고수 할 것입니다.
나는 첫 번째 방법을 선택할 것입니다.
현재 고 수량은 입고 된 재고의 합계로 계산됩니다-판매 된 재고의 합계
올바른 방법, IMO.
편집 : 또한 시스템에 대한 모든 재고 손실 / 손상을 고려하고 싶지만 당신이 그것을 다루었을 것이라고 확신합니다.
나는 이전에이 문제를 해결하는 시스템에서 일 해왔다. 이상적인 솔루션은 미리 계산 된 컬럼으로, 두 세계의 장점을 모두 얻을 수 있습니다. 총계는 어딘가의 필드이므로 비용이 많이 드는 조회는 없지만 나머지 데이터와 동기화되지는 않습니다 (데이터베이스가 무결성을 유지함). 어떤 RDMS가 미리 계산 된 열을 지원하는지 기억이 나지 않지만 트랜잭션이없는 경우에도 사용할 수 없습니다.
트리거를 사용하여 잠재적으로 미리 계산 된 열을 가짜로 만들 수 있습니다 (매우 효과적으로 ... 단점이 없음). 그래도 거래가 필요할 것입니다. IMHO, 이런 종류의 제어 된 비정규 화를 수행 할 때 데이터 무결성을 유지하는 것이 트리거에 대한 유일한 합법적 인 사용입니다.
Django-inventory 는 고정 자산에 더 중점을 두었지만 몇 가지 아이디어를 제공 할 수 있습니다.
IE : ItemTemplate (클래스)-> ItemsOnHand (인스턴스)
ItemsOnHand는 더 많은 ItemTemplate에 링크 될 수 있습니다. 예제 프린터 및 잉크 카트리지가 필요합니다. 이를 통해 각 ItemOnHand에 대한 재정렬 지점을 설정할 수도 있습니다.
Each ItemsOnHand is linked to InventoryTransactions, this allows for easy auditing. To avoid calculating actual on hand items from thousand of invetory transactions, checkpoints are used which are just a balance + a date. To calculate items on hand query to find the most recent checkpoint and start adding or substracting items to find the current balance of items. Define new checkpoints periodically.
I can see some benefit to having the two columns, but I'm not following the part about discrepancies - you seem to be implying that having the two columns (in and out) is less prone to discrepancy than a single column (current). Why is that?
Is not having one or two columns, what I meant with "totaling inventory received - total of inventory sold" is something like this:
Select sum(quantity) as inventory_received from Inventory_entry
Select sum(quantity) as inventory_sold from Sales_items
then
Qunatity_on_hand = inventory_received - inventory_sold
Please keep in mind that I oversimplified this and my initial explanation. I know there is much more to inventory that just keeping track of quantities, but in this case that's were the problem lies and what we want to fix. At this point the reason to change it is preciselly the cost of supporting the problems caused by the current design.
Also I wanted to mention that although this is not a "coding" question is related to algoritms and design which IMHO are very important topics.
Thanks everybody for your answers so far.
Nelson Marmol
We solve different problems, but our approach to some of them might be interesting to you.
We allow the system to make a "best guess", and give the users regular feedback about any of those guesses that look wrong.
To apply this to inventory, you could have 3 fields:
inventory_received
inventory_sold
estimated_on_hand
Then, you could run a process (daily?) along the lines of:
SELECT *
FROM Inventory
WHERE estimated_on_hand != inventory_received - inventory_sold
Of course, this relies on users looking at this alert, and doing something about it.
Also, you could have a function to reset inventory some how, either by updating inventory_sold/received, or perhaps adding another field "inventory_adjustment", which could be positive or negative.
... just some thoughts. Hope it's helpful.
참고URL : https://stackoverflow.com/questions/287097/inventory-database-design
'Nice programing' 카테고리의 다른 글
CORS 프리 플라이트 캐시를 전체 도메인에 적용하는 방법 (0) | 2020.10.24 |
---|---|
중복을 무시하고 Excel에서 새 고유 값 목록 만들기 (0) | 2020.10.24 |
C # : '+ = anEvent'와 '+ = new EventHandler (anEvent)'의 차이점 (0) | 2020.10.24 |
Android 애플리케이션의 성능을 테스트하는 방법은 무엇입니까? (0) | 2020.10.24 |
hg에서 파일의 변경 사항을 제거하는 방법 (0) | 2020.10.24 |