I would appreciate some advice on how to structure a database for the following scenario:
I’m using Ruby on Rails, and so I have the following tables:
- Products
- Salespeople
- Stores
Products are manufactured in batches, so each product item has a Batch code, so I think I will also need a table of batches, which refers to a product type.
- Batch
In the real world, Salespeople take Product items (from a specific Batch) and in due course issue it to a Store. Importantly, Batches are large, and may be spread across many Salespeople, and subsequently, Stores.
At some future date, I would like to run the following reports:
- Show all Batches of a Product issued to a specific Store.
- Show all Batches held by a Salesperson (i.e. not yet sold).
Now, I’m assuming I need to build a table of Transactions, something like,
- Transaction
- salesperson_id
- batch_id (through which the product can be determined)
- store_id
- typeOfTransaction (whether the Salesperson has obtained some stock, or sold some stock)
- quantity
By dynamically running through a table of Transaction records, I can could derive the above reports. However, this seems inefficient and, over time, increasingly slow.
My question is: what is the best way to keep track of transactions like this, preferably without requiring dynamic processing of all transactions to derive total items from a batch given to a given store.
I don’t believe I can just keep a central record of stock as Product comes in Batches, and Batches are distributed by Salepeople across Stores.
Thank you.
Believe it. 🙂
In my experience, the only correct way to store this kind of stuff, is to break it down to something akin to T-leger accounting, i.e. debit/credit with a chart of accounts. It requires dynamic processing to derive totals as you’ve found out, but anything short of that will lead to tricky queries when dealing with reports and audit trails.
You can speed things up significantly, by maintaining partial or complete aggregate balances using triggers (e.g. monthly stock movements per store). This will reduce the number of rows you need to sum when running larger queries. Which of these you’ll want to maintain will depend on your app and your reporting requirements.