...

Inventory Database: Build or Buy for Asset Tracking

How to set up an inventory database for asset tracking. Compare building custom databases vs buying software. SQL schemas, tools, and best practices.

Inventory Database: Build or Buy for Asset Tracking

Key Benefits

Database design for inventory tracking

Build vs buy analysis

SQL schemas and examples

Integration with tracking hardware

Inventory Database

An inventory database is the foundation of any asset tracking system. Whether you build custom or buy software, understanding database concepts helps you make better decisions and get more from your system.

Build vs Buy: The Real Costs

Building Custom

Cost CategoryYear 1Years 2-5 (per year)
Development$20,000-100,000-
Hosting$1,200-6,000$1,200-6,000
Maintenance$5,000-20,000$10,000-30,000
Bug fixesIncluded$2,000-10,000
Feature additions-$5,000-20,000
Total$26,000-126,000$18,000-66,000

Buying Software

Cost CategoryYear 1Years 2-5 (per year)
Subscription$1,200-12,000$1,200-12,000
Implementation$0-5,000-
Training$0-2,000-
Total$1,200-19,000$1,200-12,000

5-year TCO comparison:

  • Custom build: $98,000-390,000
  • SaaS software: $6,000-67,000

Build only if you have truly unique requirements that no software addresses.

When to Build Custom

Custom databases make sense when:

  • Unique workflow: Your process doesn't fit any existing software
  • Integration critical: Deep integration with proprietary systems
  • Scale extreme: Millions of transactions daily
  • Compliance specific: Regulatory requirements demand custom
  • Developer resources: In-house team with capacity

When to Buy Software

Buy off-the-shelf when:

  • Standard needs: Basic inventory tracking (most businesses)
  • Limited IT: No dedicated development resources
  • Speed matters: Need to be operational in weeks, not months
  • Budget constrained: Can't justify development costs
  • Best practices: Want proven workflows built-in

Database Design Fundamentals

If you're building custom, here's how to structure your inventory database:

Core Tables

-- Items (what you're tracking)
CREATE TABLE items (
    id SERIAL PRIMARY KEY,
    sku VARCHAR(50) UNIQUE NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    category_id INTEGER REFERENCES categories(id),
    unit_cost DECIMAL(10,2),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
 
-- Locations (where items can be)
CREATE TABLE locations (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    type VARCHAR(50), -- warehouse, vehicle, customer, etc.
    address TEXT,
    latitude DECIMAL(10,8),
    longitude DECIMAL(11,8),
    parent_id INTEGER REFERENCES locations(id)
);
 
-- Inventory (item quantities by location)
CREATE TABLE inventory (
    id SERIAL PRIMARY KEY,
    item_id INTEGER REFERENCES items(id),
    location_id INTEGER REFERENCES locations(id),
    quantity INTEGER DEFAULT 0,
    reserved_quantity INTEGER DEFAULT 0,
    last_counted TIMESTAMP,
    UNIQUE(item_id, location_id)
);
 
-- Transactions (movement history)
CREATE TABLE transactions (
    id SERIAL PRIMARY KEY,
    item_id INTEGER REFERENCES items(id),
    from_location_id INTEGER REFERENCES locations(id),
    to_location_id INTEGER REFERENCES locations(id),
    quantity INTEGER NOT NULL,
    transaction_type VARCHAR(50), -- receive, transfer, ship, adjust
    reference_number VARCHAR(100),
    user_id INTEGER REFERENCES users(id),
    notes TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

Supporting Tables

-- Categories
CREATE TABLE categories (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    parent_id INTEGER REFERENCES categories(id)
);
 
-- Users
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(100),
    role VARCHAR(50)
);
 
-- Tracking devices (GPS, RFID, etc.)
CREATE TABLE tracking_devices (
    id SERIAL PRIMARY KEY,
    device_identifier VARCHAR(100) UNIQUE,
    device_type VARCHAR(50),
    item_id INTEGER REFERENCES items(id),
    last_seen_at TIMESTAMP,
    last_latitude DECIMAL(10,8),
    last_longitude DECIMAL(11,8)
);

Common Queries

Current Inventory by Location

SELECT
    l.name as location,
    i.sku,
    i.name as item_name,
    inv.quantity,
    inv.reserved_quantity,
    (inv.quantity - inv.reserved_quantity) as available
FROM inventory inv
JOIN items i ON inv.item_id = i.id
JOIN locations l ON inv.location_id = l.id
WHERE inv.quantity > 0
ORDER BY l.name, i.name;

Item Movement History

SELECT
    t.created_at,
    i.name as item,
    fl.name as from_location,
    tl.name as to_location,
    t.quantity,
    t.transaction_type,
    u.name as performed_by
FROM transactions t
JOIN items i ON t.item_id = i.id
LEFT JOIN locations fl ON t.from_location_id = fl.id
LEFT JOIN locations tl ON t.to_location_id = tl.id
JOIN users u ON t.user_id = u.id
WHERE i.sku = 'ASSET-001'
ORDER BY t.created_at DESC;

Low Stock Alert

SELECT
    i.sku,
    i.name,
    SUM(inv.quantity) as total_quantity,
    i.reorder_point
FROM items i
JOIN inventory inv ON i.id = inv.item_id
GROUP BY i.id, i.sku, i.name, i.reorder_point
HAVING SUM(inv.quantity) <= i.reorder_point;

Database Selection

PostgreSQL

Best for: Most custom inventory systems

  • Robust and reliable
  • Excellent SQL compliance
  • Good JSON support
  • Strong community
  • Free and open source

MySQL

Best for: Simpler requirements, WordPress integration

  • Fast reads
  • Wide hosting support
  • Simple setup
  • Good for web applications

SQLite

Best for: Single-user, local applications

  • No server required
  • File-based
  • Good for prototypes
  • Limited concurrency

MongoDB

Best for: Highly variable item attributes

  • Flexible schema
  • Good for varying product attributes
  • Document-based
  • Requires different design approach

Integrating Tracking Hardware

GPS Tracker Integration

Store location updates from GPS devices:

-- Receive GPS update
INSERT INTO location_updates (
    tracking_device_id,
    latitude,
    longitude,
    accuracy,
    battery_level,
    recorded_at
) VALUES ($1, $2, $3, $4, $5, NOW());
 
-- Update device last known location
UPDATE tracking_devices
SET
    last_latitude = $2,
    last_longitude = $3,
    last_seen_at = NOW()
WHERE id = $1;

RFID Integration

Record RFID scans:

-- Record RFID scan at checkpoint
INSERT INTO rfid_scans (
    rfid_tag,
    reader_id,
    location_id,
    scan_time
) VALUES ($1, $2, $3, NOW());
 
-- Update item location based on scan
UPDATE inventory
SET location_id = $3
WHERE item_id = (
    SELECT item_id FROM tracking_devices WHERE device_identifier = $1
);

Performance Considerations

Indexing

Essential indexes for inventory databases:

-- Item lookups
CREATE INDEX idx_items_sku ON items(sku);
CREATE INDEX idx_items_category ON items(category_id);
 
-- Inventory queries
CREATE INDEX idx_inventory_item ON inventory(item_id);
CREATE INDEX idx_inventory_location ON inventory(location_id);
 
-- Transaction history
CREATE INDEX idx_transactions_item ON transactions(item_id);
CREATE INDEX idx_transactions_date ON transactions(created_at);
CREATE INDEX idx_transactions_type ON transactions(transaction_type);

Partitioning

For large transaction tables:

-- Partition transactions by month
CREATE TABLE transactions_2025_01 PARTITION OF transactions
    FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');

The Easier Path: SaaS Software

Unless you have specific requirements demanding custom development, SaaS inventory software provides:

  • Immediate availability: Start using today
  • Proven design: Database decisions already made
  • Ongoing updates: Features without development cost
  • Support included: Help when things go wrong
  • Integrations built-in: Connect to common systems
  • Mobile access: Apps without building them

AirPinpoint provides inventory tracking without database decisions—just add trackers and go.

Making the Decision

Choose Custom Database If:

  • Unique workflows that no software handles
  • Integration with proprietary systems is critical
  • You have developer resources for ongoing maintenance
  • Compliance requires custom data handling
  • Scale demands custom optimization

Choose SaaS Software If:

  • Standard inventory tracking needs
  • Limited technical resources
  • Need to be operational quickly
  • Want proven best practices
  • Prefer predictable costs

For most businesses, the database question is answered by choosing the right software—let someone else manage the database while you focus on your business.

How Our Technology Works

AirPinpoint uses Apple AirTags via the FindMy network to provide reliable asset tracking without the need for cellular connections.Learn more about how AirTags work →

AirPinpoint Tracking Device

Bluetooth Low Energy

Uses minimal power while maintaining reliable connections to nearby devices in the network.

Long Battery Life

Designed for up to 7+ years of battery life, making it ideal for long-term asset tracking.

Apple FindMy Network

Leverages a vast network of billions of connected Apple devices to locate your assets anywhere.

Precision Location

Get accurate location data and movement history for all your tracked assets.

"We built a custom inventory database thinking it would save money. After 2 years of maintenance headaches, we switched to software that just works."

Feature
Our SolutionOur Solution
Geotab GO
Rooster Tag
LandAirSea 54
Samsara Asset Tag
Samsara GPS Tracker
Size31x31 mm111x71x29.5 mm50.8 mm x 19.1 mm~57.8x24 mm~63.5x25.4 mm~108x86x25 mm
Battery Life3-7+ years (live tracking)3 years (1 update/day), 2 weeks (live)Up to 5 years1-3 weeks4 years3 years (2 updates per day), 2 weeks (live)
TechnologyAirTagGPSBluetoothGPSBluetoothGPS (not live)
CoverageWorldwideWorldwideUp to 0.5 miGlobalGateway-dependentWorldwide
DurabilityRugged, waterproofRuggedRuggedizedIP67 waterproofUltra ruggedIP67 waterproof
Gateway RequiredNoNoYesNoYesNo
* Comparison based on publicly available information as of 1/8/2026

Frequently Asked Questions

Ready to start tracking your assets?

Get started today with AirPinpoint's advanced tracking solution and never lose track of your valuable assets again.