Database design question

Anonymous
2025-05-29T12:13:35+00:00

Howdy. I have an inventory database. I want to track where something is, and track the transactions when moving the item around. So currently I have a table for the items, of course, as well as one for the transactions, and types of transactions.

If something is assigned to a person, marked as lost, placed in a storage location, put on a piece of equipment, sent off for repair. Each of those, except the marked as lost transaction, is associated with a different table. Personnel, locations, equipment, repair vendors.

For the transaction table, I have one field for the type of transaction, and then one field for each foreign key for the different tables. For the item table, there's also a field for each foreign key. The system clears the field for where it's currently at, and assigns the foreign key value to the appropriate field for it's new location. (Item A was assigned to Todd, so the EmployeeID field was 623. It's reassigned to the front loader. So EmployeeID is cleared, and EquipmentID is now 1020.)

I felt at the time that this wasn't a great way to do it, but it's all I could figure out at the time and in the timeframe I had.

In expanding and improving the program, I'm wondering about fixing/doing it correctly.

Is the 'right' way to do it one field for the type of transaction/category of where it is, and then one field for the foreign key of that category? There wouldn't be a relationship between the foreign key and that field in that case.

Or maybe having all the locations be one table, and then just a field in that table say what type of location (place, employee, equipment) it is? But that leaves me with wondering how to deal with the employees. I'm certain merging employees, equipment, and storage locations isn't right.

Microsoft 365 and Office | Access | Other | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. ScottGem 68,755 Reputation points Volunteer Moderator
    2025-05-29T14:20:29+00:00

    Your transaction table should have a field for TransactionTypeID and for LocationID. If you want to maintain a history of locations, you could have a history table with Item, TrnsactionType and Location and EffectiveDate.

    0 comments No comments
  2. Anonymous
    2025-05-29T14:33:11+00:00

    That's what I was thinking with the "Is the 'right' way to do it one field for the type of transaction/category of where it is, and then one field for the foreign key of that category?" part. So say assigned to a person is Transaction type 1. TransactionTypeID = 1 for that transaction, then the LocationID = (whatever the employees EmployeeID is). Then if stored in a location is transaction type 2, another transaction would be TransactionTypeID = 2 and LocationID = (whatever the StorageLocationID is). And any forms showing the transactions would just use VBA to determine which table to pull information from to display people and location names (as well as the other types)?

    0 comments No comments
  3. Anonymous
    2025-05-29T16:02:53+00:00

    It seems to me that the different relationship types are distinct, and should be modelled by separate tables which resolve the many-to-many relationship types into two one-to-many relationship types in each case. So you'd have EquipmentPersonnel, EquipmentStrorageLocations, etc tables. Two things are crucial to the way in which the data is both input and presented for output, in a report say:

    1. Firstly, each relationship should have columns to record the date range during which the relationship is active. This would be particularly important for the output mechanism, as I'll describe below.
    2. Also important for the output mechanism is that the other attributes of each relationship type should be such that they can each be each be returned in a similar format when output as a single column.

    For data entry there would be multiple subforms per item of equipment, each based on the table modelling that particular relationship type.

    For output in a report or similar, to combine each of the relationship types per item of equipment the rows from the tables modelling the relationship types would be brought together into a single result set by means of UNION operations. This is where it is important that the columns in each table modelling a relationship type are such that each can be returned as a single column by the UNION operation. The date columns in each of the tables would be used to determine the order in which rows are returned. So one row might return the movement of an item to a storage location, and the next row its subsequent assignment to an employee.

    I have done something similar in my Inventory demo database with the following query:

    SELECT "Acquisition" AS MovementType, ProductID, Quantity
    FROM StockAcquisitions
    WHERE AcquisitionDate >=
    NZ((SELECT MAX(StockTakeDate)
    FROM StockTakes
    WHERE StockTakes.ProductID = StockAcquisitions.ProductID))
    UNION ALL
    SELECT "Disposal", ProductID, Quantity*-1
    FROM StockDisposals
    WHERE DisposalDate >=
    NZ((SELECT MAX(StockTakeDate)
    FROM StockTakes
    WHERE StockTakes.ProductID = StockDisposals.ProductID))
    UNION ALL
    SELECT "Stocktake", ProductID, Quantity
    FROM StockTakes AS ST1
    WHERE StockTakeDate=
    (SELECT MAX(StockTakeDate)
    FROM StockTakes AS ST2
    WHERE ST2.ProductID = ST1.ProductID);
    UNION ALL
    SELECT "Sale", ProductID, Quantity*-1
    FROM Orders INNER JOIN OrderDetails
    ON Orders.OrderNumber = OrderDetails.OrderNumber
    WHERE OrderDate >=
    NZ((SELECT MAX(StockTakeDate)
    FROM StockTakes
    WHERE StockTakes.ProductID = OrderDetails.ProductID));

    Note that the ordering of the rows is done by means of the report's internal sorting and grouping mechanism, not by an ORDER BY clause in the query.

    0 comments No comments