Designing a Logistics ERD for Vending Machine Route Optimization with PlantUML

In the fast-paced world of logistics and supply chain management, operational efficiency hinges on precise data modeling. For a fleet of vending machines spread across a city or region, the challenge is not just delivering products but doing so with optimized routes and timely coin collection. Without a robust data structure, dispatchers struggle to track which machines are running low on stock, which drivers are available, and how to group stops to minimize fuel and time costs. A well-designed Entity-Relationship Diagram (ERD) serves as the architectural blueprint for the database that powers these critical operational decisions.

Real-world system context and operational workflow illustration

By visualizing the relationships between vending machines, locations, inventory levels, route plans, and service schedules, architects can ensure that the underlying database supports real-time restocking requirements and efficient fleet management. This tutorial guides you through constructing a professional ERD using PlantUML, a powerful diagram-as-code language. We will focus on the specific entities required to manage a restock route optimization system, including the logic for assigning drivers, tracking coin collections, and scheduling future services. Using VPasCode, you can write this code directly in the browser and see the diagram render instantly, allowing for rapid iteration and refinement of your logistics data model.

Understanding the Model: Purpose, Scope & Problem Framing

Before diving into the syntax, it is crucial to understand the domain abstraction we are modeling. An Entity-Relationship Diagram is the standard method for visualizing the logical structure of a database. In this specific logistics scenario, the diagram must capture static data (like machine locations and product definitions) and dynamic operational data (like active routes and coin collection records).

Diagram Abstraction & Representation
The core of this model revolves around the VendingMachine as the central entity. Every other entity relates back to a machine or a route involving machines. We represent Locations to geospatially map the fleet, Products to define inventory, and RoutePlans to organize the daily workflow. The diagram uses crow’s foot notation to clearly indicate cardinality: one-to-one relationships for unique identifiers, and one-to-many relationships for things like a single machine having multiple inventory items or a single route containing multiple stops.

Target Domain Scope & Scenario
The scope of this ERD is strictly limited to the operational layer of a vending logistics system. It does not model customer billing or e-commerce transactions. Instead, it focuses on the “last mile” of the supply chain: the physical movement of goods and cash. The diagram covers the lifecycle of a restock event, from identifying a low stock level (generating a RestockRequirement) to executing the trip (creating a RoutePlan with RouteStops) and finally collecting the revenue (CoinCollection).

Key Takeaways & Educational Insights
By building this diagram, you will learn how to normalize data to avoid redundancy (e.g., separating Product definitions from MachineInventory counts). You will also see how to handle temporal data, such as planned_arrival vs. actual_arrival, which is critical for performance analytics. The model demonstrates how to link a Driver and a Vehicle to a specific Route, ensuring that resource allocation is traceable.

Complete Diagram & Full Source Code

Below is the complete, rendered visualization of the Vending Machine Restock Route Optimization and Coin Collection Scheduling System ERD. This diagram encapsulates all the entities and relationships discussed, providing a clear overview of the data architecture.

Complete ERD for Vending Machine Restock Route Optimization and Coin Collection Scheduling System

@startuml
!theme cerulean
title Vending Machine Restock Route Optimization and Coin Collection Scheduling System ERD

/' 
Diagram Context:
This ERD models the core data structures needed to manage a vending machine
fleet, plan efficient restock routes, and schedule coin collection visits.
It captures machines, their locations, product inventory levels, restock
requirements, route plans, route stops, drivers, vehicles, coin collection
records, and service schedules. The diagram supports operational decisions
such as which machines need restocking, how to group stops into optimized
routes, when coin boxes should be collected, and which staff or vehicles
are assigned to execute the work.
'/

entity "VendingMachine" as VM {
  * machine_id : INT <<PK>>
  --
  asset_tag : VARCHAR
  machine_type : VARCHAR
  status : VARCHAR
  installation_date : DATE
  last_service_date : DATE
  location_id : INT <<FK>>
}

entity "Location" as LOC {
  * location_id : INT <<PK>>
  --
  site_name : VARCHAR
  address_line1 : VARCHAR
  address_line2 : VARCHAR
  city : VARCHAR
  state : VARCHAR
  postal_code : VARCHAR
  latitude : DECIMAL
  longitude : DECIMAL
  access_notes : TEXT
}

entity "Product" as PROD {
  * product_id : INT <<PK>>
  --
  sku : VARCHAR
  product_name : VARCHAR
  category : VARCHAR
  unit_price : DECIMAL
  package_size : VARCHAR
}

entity "MachineInventory" as INV {
  * inventory_id : INT <<PK>>
  --
  machine_id : INT <<FK>>
  product_id : INT <<FK>>
  current_quantity : INT
  par_level : INT
  reorder_threshold : INT
  last_updated : DATETIME
}

entity "RestockRequirement" as REQ {
  * requirement_id : INT <<PK>>
  --
  machine_id : INT <<FK>>
  product_id : INT <<FK>>
  required_quantity : INT
  priority : VARCHAR
  requested_at : DATETIME
  fulfilled : BOOLEAN
}

entity "RoutePlan" as ROUTE {
  * route_id : INT <<PK>>
  --
  route_date : DATE
  route_status : VARCHAR
  planned_start_time : DATETIME
  planned_end_time : DATETIME
  total_distance_km : DECIMAL
  estimated_duration_min : INT
  driver_id : INT <<FK>>
  vehicle_id : INT <<FK>>
}

entity "RouteStop" as STOP {
  * stop_id : INT <<PK>>
  --
  route_id : INT <<FK>>
  machine_id : INT <<FK>>
  stop_sequence : INT
  planned_arrival : DATETIME
  actual_arrival : DATETIME
  service_type : VARCHAR
  stop_status : VARCHAR
}

entity "Driver" as DRIVER {
  * driver_id : INT <<PK>>
  --
  first_name : VARCHAR
  last_name : VARCHAR
  phone : VARCHAR
  license_number : VARCHAR
  availability_status : VARCHAR
}

entity "Vehicle" as VEH {
  * vehicle_id : INT <<PK>>
  --
  plate_number : VARCHAR
  make : VARCHAR
  model : VARCHAR
  capacity_units : INT
  status : VARCHAR
}

entity "CoinCollection" as COIN {
  * collection_id : INT <<PK>>
  --
  machine_id : INT <<FK>>
  route_id : INT <<FK>>
  collection_datetime : DATETIME
  coin_amount : DECIMAL
  bill_amount : DECIMAL
  cash_total : DECIMAL
  meter_reading : DECIMAL
  collector_driver_id : INT <<FK>>
}

entity "ServiceSchedule" as SCHED {
  * schedule_id : INT <<PK>>
  --
  machine_id : INT <<FK>>
  schedule_type : VARCHAR
  frequency_days : INT
  next_service_date : DATE
  last_service_date : DATE
  active : BOOLEAN
}

VM ||--|| LOC : located_at
VM ||--o{ INV : has_inventory
PROD ||--o{ INV : stocked_as
VM ||--o{ REQ : generates
PROD ||--o{ REQ : requested_product
ROUTE ||--o{ STOP : includes
VM ||--o{ STOP : visited_at
DRIVER ||--o{ ROUTE : assigned_to
VEH ||--o{ ROUTE : used_for
VM ||--o{ COIN : collects_from
ROUTE ||--o{ COIN : collection_during
DRIVER ||--o{ COIN : performs_collection
VM ||--o{ SCHED : scheduled_for

@enduml

Step-by-Step Architectural Walkthrough

Building a complex ERD requires a structured approach. We will break down the construction of this diagram into four logical phases, moving from the canvas setup to the final relationships.

Phase 1: Canvas Configuration & Layout Directives

Every PlantUML diagram begins with configuration directives that set the visual tone and layout. In this logistics model, we want a clean, professional look that is easy to read. We start by declaring the diagram type and applying a specific theme.

@startuml
!theme cerulean

The @startuml directive signals the beginning of the diagram code. The !theme cerulean directive applies the “Cerulean” theme, which uses a blue-and-white color scheme suitable for enterprise and logistics applications. This ensures the diagram looks polished immediately without needing manual styling of every element.

Phase 2: Declaring Core Entities, Actors, and Boundaries

Next, we define the core entities. In PlantUML ERD, we use the entity keyword followed by the entity name in quotes and an alias for brevity. Inside the curly braces, we define the attributes, data types, and keys.

entity "VendingMachine" as VM {
  * machine_id : INT <>
  --
  asset_tag : VARCHAR
  location_id : INT <>
}

Notice the use of * before the primary key attribute (machine_id) to indicate it is the Primary Key. The <<PK>> stereotype further reinforces this in the rendered diagram. The double dash -- acts as a separator, visually grouping the key attributes from the optional or descriptive attributes (like asset_tag and location_id). We repeat this pattern for Location, Product, Driver, and Vehicle, ensuring each has a unique identifier.

Phase 3: Mapping Data Flows & Key Interactions

With the static entities defined, we now model the dynamic relationships. In a logistics system, the flow of information is critical. We use the ||--o{ syntax to represent relationships. The || indicates a mandatory one-to-one or one-to-many relationship, while o{ indicates an optional one-to-many relationship.

VM ||--o{ INV : has_inventory
PROD ||--o{ INV : stocked_as

Here, we establish that a VendingMachine (VM) can have zero or many MachineInventory (INV) records (a machine might be empty, or stocked with many products). Similarly, a Product (PROD) can be stocked in many inventory records. We also define the operational links: a Driver is assigned to a Route, and a Route includes multiple RouteStops.

Phase 4: Grouping, Annotations & Visual Polish

The final phase involves adding context and ensuring the diagram tells a complete story. We add a title to the diagram and use a comment block to provide a high-level summary for anyone reading the code or the rendered image. The comment block is wrapped in /' and '/ to keep it hidden from the renderer but visible in the source code for documentation purposes.

title Vending Machine Restock Route Optimization and Coin Collection Scheduling System ERD

/' 
Diagram Context:
This ERD models the core data structures needed to manage a vending machine
fleet...
'/

This section also ensures that all foreign keys (marked with <<FK>>) are explicitly declared in the entity definitions, which helps developers understand the database schema constraints at a glance.

Syntax & Keyword Deep Dive

To master PlantUML ERD, you need to understand the specific syntax used to define structure and relationships. Here is a breakdown of the key elements used in this logistics diagram:

  • entity: The keyword used to define a new table or entity. It takes a display name (e.g., "VendingMachine") and an alias (e.g., as VM).
  • * (Asterisk): Placed before an attribute name (e.g., * machine_id) to denote the Primary Key (PK) visually in the diagram.
  • <<PK>> and <<FK>>: These are stereotypes used to explicitly label Primary Keys and Foreign Keys in the rendered output, ensuring clarity for database architects.
  • -- (Double Dash): A visual separator line within an entity block, used to distinguish key attributes from regular attributes.
  • ||--o{: A relationship connector. || means “mandatory one” and o{ means “zero or many”. For example, a VendingMachine ||--o{ RouteStop means a machine must be part of a stop logic but a stop can exist for a machine (depending on logic) or a machine can have many stops over time. In this specific model, it represents a one-to-many relationship where the cardinality is enforced.
  • title: Sets the main title of the diagram, which appears at the top of the rendered output.
  • !theme: A directive to apply a predefined color scheme and font style to the entire diagram.

Best Practices & Pitfalls to Avoid

When modeling complex logistics systems like this, adherence to best practices ensures your diagram remains maintainable and useful.

  • Use Consistent Naming Conventions: Always use the same naming style for entities and aliases. In this diagram, we used uppercase for entity names (e.g., VendingMachine) and uppercase aliases (e.g., VM). This consistency makes the diagram easier to scan and the code easier to read.
  • Separate Static and Dynamic Data: Notice how we separated Product (static catalog) from MachineInventory (dynamic state). A common pitfall is combining these into one table, which leads to data redundancy and update anomalies. Keep your reference data separate from transactional data.
  • Define Cardinality Clearly: Use the correct relationship symbols. Using --o{ (optional) when a relationship is mandatory (like a Stop belonging to a Route) can lead to database integrity issues later. Ensure the diagram reflects the actual business rules.
  • Document with Comments: Use the /' ... '/ comment block to explain the scope of the diagram. As the system grows, new developers will appreciate a high-level summary of what the model represents.

Start Building Logistics ERDs Faster with VPasCode

Instantly visualize and refine your vending machine fleet data models in your browser with zero setup, no local installation, and free access to our interactive PlantUML editor.

Scroll to Top