Microsoft Access can be used to build reliable business applications, but the quality of the application depends heavily on the design of the database underneath it. Many problems that appear later—duplicate data, difficult queries, unreliable reports, slow forms, and expensive maintenance—begin with decisions made before the first form is built.
This guide explains practical database-design principles for Microsoft Access and uses a realistic warehouse and inventory scenario to show how those principles work together. It also explains when an Access application should remain an Access solution and when SQL Server becomes a better data platform.
A Realistic Warehouse Example
Consider a company operating a warehouse that receives products from suppliers and ships them to customers. The business needs to manage products, suppliers, customers, warehouses, inventory, purchase orders, receiving, sales orders, shipping, inventory adjustments, and employees.
A simplified relational design might include:
- tblProducts — product master data.
- tblSuppliers — supplier information.
- tblProductSuppliers — which suppliers can provide which products.
- tblCustomers — customer information.
- tblWarehouses — warehouse locations.
- tblInventory — current inventory by product and warehouse.
- tblInventoryTransactions — receipts, shipments, adjustments, transfers, and other stock movements.
- tblOrders and tblOrderDetails — customer orders and their line items.
- tblPurchaseOrders and tblPurchaseOrderDetails — purchasing activity.
- tblReceipts and tblReceiptDetails — goods received.
This is intentionally simplified. A production warehouse system may also require bin locations, lots, serial numbers, units of measure, shipments, employees, cycle counts, returns, and other entities. The important point is to model each logical subject separately and connect the subjects through keys and relationships.
1. Putting Everything Into One Table
One of the most common mistakes is creating one large table containing product, supplier, customer, warehouse, order, and inventory information.
For example, a warehouse might initially create records containing:
| Product | Supplier | Warehouse | Customer | Quantity | Order Date |
|---|---|---|---|---|---|
| ABC-100 | Acme Supply | Newark | ABC Retail | 50 | 10/01/2026 |
| ABC-100 | Acme Supply | Newark | XYZ Retail | 25 | 10/02/2026 |
| DEF-200 | Global Parts | Newark | ABC Retail | 100 | 10/02/2026 |
This looks manageable with a few records. At scale, however, the same supplier, customer, product, and warehouse information is repeated over and over.
A better design gives each logical subject its own table and connects those tables with primary and foreign keys. This reduces duplication and makes changes much safer.
2. Using the Wrong Primary Key
Each important table should normally have a primary key that uniquely identifies each record. In Access, an AutoNumber field is often appropriate for an internal primary key.
For example, ProductID can identify a product record while SKU remains the business identifier used by the warehouse.
| ProductID | SKU | ProductName |
|---|---|---|
| 1 | ABC-100 | Widget A |
| 2 | DEF-200 | Widget B |
The internal key and the business identifier serve different purposes. If the business changes its SKU convention later, relationships based on a stable internal key do not have to be redesigned.
If duplicate SKUs are not allowed, enforce that rule with a unique index or other appropriate constraint rather than relying only on application code.
3. Storing the Same Data Multiple Times
Suppose Acme Supply provides 500 products. Storing the supplier’s address and phone number on every product or purchase-order record creates unnecessary duplication.
Instead, store supplier information once in tblSuppliers and use SupplierID where the supplier is referenced.
This is especially important when information changes. A supplier’s phone number should normally be updated in one place, not in hundreds of historical transaction records.
4. Assuming Every Product Has Only One Supplier
A common shortcut is to put SupplierID directly in tblProducts. That works only if the business rule is truly “one product has exactly one supplier.” Many warehouses do not have that rule.
If Product ABC-100 can be purchased from three suppliers, the relationship is many-to-many:
Product ↔ Supplier
Use a junction table such as tblProductSuppliers:
- ProductSupplierID
- ProductID
- SupplierID
- SupplierPartNumber
- Cost
- IsPreferred
This design can also store supplier-specific information such as the supplier’s part number, purchase cost, lead time, or preferred-supplier status.
5. Creating Relationships Without Understanding Cardinality
Relationships are not simply lines drawn between tables. They represent business rules.
Examples include:
- One customer → many orders
- One order → many order details
- One warehouse → many inventory records
- One product → many inventory records across warehouses
- Many products ↔ many suppliers
An order containing multiple products is a classic header/detail design.
tblOrders contains the order header, such as OrderID, CustomerID, OrderDate, and Status.
tblOrderDetails contains OrderDetailID, OrderID, ProductID, Quantity, and UnitPrice.
This structure maps naturally to an Access main form with a subform: the order is the main form and the order lines are displayed in the subform.
6. Using Repeating Fields Instead of Related Records
A design such as Product1, Qty1, Product2, Qty2, and Product3, Qty3 is a warning sign. What happens when a shipment contains 20 products?
The better solution is a header/detail structure. For example:
tblReceipts stores the receipt header, such as ReceiptID, SupplierID, ReceiptDate, and WarehouseID.
tblReceiptDetails stores ReceiptDetailID, ReceiptID, ProductID, and QuantityReceived.
Now a receipt can contain two products or two hundred products without changing the database structure.
7. Treating Access Lookup Fields as a Substitute for Relationships
Access provides lookup fields that can make table datasheets appear convenient, but a table-level Lookup field should not be confused with a database relationship.
For a robust design:
- Store the foreign key in the table, such as SupplierID.
- Define the actual relationship between the tables.
- Use a combo box on an Access form to let users select a supplier by name.
- Let the combo box display meaningful text while storing the underlying key.
For example, a warehouse employee can select Acme Supply from a combo box while the form stores SupplierID = 17.
That keeps the user interface friendly without hiding the relational structure from the developer.
8. Storing Data as Presentation Text
Store values according to what they are, not according to how they should look on a screen.
For example, inventory quantity should be stored as a numeric value such as 1250, not as the text “1,250 Units.” A form or report can format the value for the user.
Likewise, store an actual Date/Time value rather than text such as “October 5, 2026” when the value needs to be sorted, filtered, compared, or used in calculations.
Correct data types make queries, validation, calculations, and reporting much easier.
9. Ignoring Data Integrity and Audit Information
Good design is not only about tables and relationships. The database should also protect the quality of its data.
Depending on the application, consider:
- Referential integrity between parent and child tables.
- Validation rules for required or restricted values.
- Unique indexes where duplicate values are not permitted.
- CreatedDate and ModifiedDate fields for important business records.
- CreatedBy or ModifiedBy where accountability is required.
For example, a warehouse should not normally be able to create an order detail for a ProductID that does not exist.
10. Treating Current Inventory as the Entire Inventory Model
A simple tblInventory table containing QuantityOnHand and QuantityAllocated can be useful as a current snapshot, but it is often not enough for a real warehouse application.
If inventory changes from 150 units to 130 units, a good system should be able to answer why.
That is where an inventory transaction or stock-movement table becomes important.
tblInventoryTransactions might contain:
- InventoryTransactionID
- ProductID
- WarehouseID
- TransactionDate
- TransactionType
- Quantity
- ReferenceID
- CreatedBy
Transaction types could include Receipt, Shipment, Adjustment, Transfer, or Return.
This gives the business an audit trail. It can explain how inventory changed and support reconciliation when physical counts do not match system quantities.
For more advanced systems, current inventory can be derived from transactions or maintained as a controlled snapshot for performance. The right choice depends on transaction volume and application requirements.
11. Designing Only for Today
A warehouse database may start with 5,000 products and one warehouse. Two years later, the company may have several warehouses, more users, a much larger transaction history, and integrations with an ERP or WMS.
Before building the application, ask:
- Could more warehouses be added?
- Will products have multiple suppliers?
- Could bin locations, lots, or serial numbers become necessary?
- Will users need barcode scanning?
- Will the database connect to an ERP, WMS, or e-commerce platform?
- How many transactions could accumulate?
- How many users might access the application at the same time?
Planning for reasonable growth does not mean over-engineering a small application. It means avoiding design choices that make future changes unnecessarily expensive.
12. Ignoring Multi-User Access Architecture
A warehouse application may be used by receiving, inventory control, picking, shipping, supervisors, and management at the same time.
For a multi-user Access application, a common architecture is to split the database:
- Front end: forms, reports, queries, VBA, and application logic.
- Back end: shared data tables.
Each user should normally have their own local copy of the Access front end while the back-end data is stored in a shared, reliable location.
This is different from having every user open the same front-end ACCDB over the network.
Network reliability also matters. Access is a file-based database, so unstable connections, poor Wi-Fi, or inappropriate remote/VPN deployments can increase the risk of performance problems or database corruption.
For larger or more demanding applications, Access can remain the user interface while SQL Server becomes the back-end database.
When Should an Access Database Move to SQL Server?
Not every Access application needs SQL Server. Access remains a practical choice for many departmental and small-business applications.
However, SQL Server becomes increasingly attractive when requirements include:
- Large or rapidly growing datasets.
- Many simultaneous users or high transaction volume.
- More demanding backup, recovery, or security requirements.
- Integration with multiple applications or services.
- Reliable server-side processing.
- Remote or distributed access requirements.
- Data that needs to be shared by several applications.
One important technical constraint is the 2 GB maximum size of an individual Access database file, excluding the space used by system objects. The practical limit can be reached sooner depending on indexes, temporary objects, attachments, and application design.
SQL Server can also provide a path for an existing Access application to grow without requiring the user interface to be completely replaced.
A common architecture is:
Access front end → SQL Server back end
In that architecture, Access can continue to provide forms, reports, and familiar business workflows while SQL Server handles the central data store.
The migration decision should be based on actual requirements rather than an arbitrary record count or user number.
Where AI Fits Into Database Design
AI does not eliminate the need for good database design. In many business applications, the opposite is true: clean, structured data makes AI much more useful.
A well-designed warehouse database can provide a reliable foundation for capabilities such as:
- Extracting product, quantity, and supplier information from invoices or purchase orders.
- Classifying documents and routing them into business workflows.
- Identifying unusual inventory movements or order patterns.
- Allowing authorized users to ask natural-language questions about business data.
- Assisting with data cleansing and product classification.
For example, an AI system may extract a purchase order from a PDF. That information still needs to be mapped correctly to Products, Suppliers, Purchase Orders, and Purchase Order Details.
AI can help process information, but it should not be used as a substitute for a sound data model, validation rules, security controls, or human review where business accuracy matters.
A Practical Database Design Checklist
Tables
- Does each table represent one logical subject?
- Is duplicate information minimized?
- Are repeating groups stored as related records?
- Have many-to-many relationships been identified?
Keys and Relationships
- Does each important table have a primary key?
- Are foreign keys used consistently?
- Are relationships based on actual business rules?
- Is referential integrity appropriate for the application?
Data Quality
- Are numbers stored as numbers?
- Are dates stored as Date/Time values?
- Are unique values protected with appropriate indexes?
- Are important records auditable?
Access Architecture
- Is the database split into front end and back end where appropriate?
- Does each user have a local front end?
- Is the network environment reliable?
- Could the application eventually use SQL Server as its back end?
Future Growth
- How many records are expected?
- How many users will access the application?
- Could more warehouses or locations be added?
- Could other systems need access to the data?
- Could AI or automation eventually be added?
The Most Important Principle
Good database design is not about making an Access database complicated. It is about making the structure logical, consistent, maintainable, and appropriate for the business.
A warehouse application is a good example. Products, suppliers, customers, inventory, orders, receiving, and shipping are different business subjects, but they become a useful system when they are connected through a well-designed relational model.
Before creating the first form, spend time designing the tables, keys, relationships, data types, and business rules.
Build the database structure correctly first. Then build the application on top of it.
Final Takeaway
Microsoft Access remains a capable platform for building business applications, but the quality of an Access solution depends heavily on the quality of its underlying data model.
Good design also gives you options. A well-structured Access application can remain an Access solution when that is appropriate, or evolve into an Access front end connected to SQL Server as requirements grow.
And when AI is added later, a clean relational database gives that AI a much stronger foundation to work from.
Design the data first. Build the application second. Add AI where it creates real business value.
