offdataai
Travel & Hospitality · data model template

Restaurant POS data model

Normalized (3NF) restaurant POS model. Location to menu to menu-item with modifiers defines the offer; orders against tables and servers carry order-items (with chosen modifiers) that fire kitchen tickets and settle via payments, while recipes tie menu items to ingredient inventory. Staff PII and card data are classified and masked.

Restaurant point-of-sale and back-of-house operations: locations and their menus, items, and modifiers; dine-in tables and staff; the order/order-item/kitchen-ticket chain with payments; and the inventory side of ingredients and recipes that deplete stock per sold item — modeled as a normalized OLTP POS schema with staff and card data masked. It is a normalized (3NF) relational model that mirrors the source system, suited to operational databases and to landing source data faithfully.

3NFTravel & HospitalityGDPRPCI DSS
13
tables
115
columns
17
relationships
5
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: PostgreSQL). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

locations_and_menufront_of_housekitchen_and_paymentinventory

Design decisions

  • Order / order-item / modifier hierarchy

    A guest check is a header with line items, each of which may carry multiple modifier choices; modeling order, order_item, and a modifier junction keeps customizations normalized and priceable.

  • Recipe as a menu-item-to-ingredient junction

    Each menu item consumes many ingredients and each ingredient feeds many items, so a recipe junction captures the M:N bill of materials that drives inventory depletion.

  • Kitchen ticket separate from the order

    Sending a check to the kitchen produces one or more KDS tickets by station with their own lifecycle, distinct from the front-of-house order and payment flow.

  • Normalized (3NF) rather than dimensional

    POS handling is high-volume transactional with open checks, voids, and live inventory updates where relational integrity is paramount.

Tables in the Restaurant POS model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Tables (13)

location

Grain: one row per restaurant location

Restaurant site.

ColumnTypeKeys
location_keybigintPK
location_codevarcharBK
location_namevarchar
addressvarchar
cityvarchar
countryvarchar
timezonevarchar
seating_capacityinteger
currencyvarchar
opened_datedate
is_activeboolean

menu

Grain: one row per menu at a location

Day-part / seasonal menu.

ColumnTypeKeys
menu_keybigintPK
location_keybigint
menu_codevarcharBK
menu_namevarchar
menu_typevarchar
active_fromdate
active_todate
is_activeboolean

menu_item

Grain: one row per sellable menu item

Sellable item.

ColumnTypeKeys
menu_item_keybigintPK
menu_keybigint
item_codevarcharBK
item_namevarchar
descriptionvarchar
categoryvarchar
pricedecimal
tax_ratedecimal
caloriesinteger
is_alcoholboolean
prep_minutessmallint
is_availableboolean

modifier

Grain: one row per item modifier option

Item customization option.

ColumnTypeKeys
modifier_keybigintPK
menu_item_keybigint
modifier_namevarchar
modifier_groupvarchar
price_deltadecimal
is_defaultboolean

dining_table

Grain: one row per physical table

Dine-in table.

ColumnTypeKeys
dining_table_keybigintPK
location_keybigint
table_numbervarcharBK
sectionvarchar
seatssmallint
statusvarchar

staff

Grain: one row per staff member

Employee record.

ColumnTypeKeys
staff_keybigintPK
location_keybigint
staff_numbervarcharBK
first_namevarcharPII
last_namevarcharPII
rolevarchar
emailvarcharPII
phonevarcharPII
hire_datedate
hourly_ratedecimal
is_activeboolean

order

Grain: one row per order (check)

Guest check header.

ColumnTypeKeys
order_keybigintPK
location_keybigint
dining_table_keybigint
staff_keybigint
order_numbervarcharBK
order_typevarchar
guest_countsmallint
subtotal_amountdecimal
tax_amountdecimal
tip_amountdecimal
total_amountdecimal
statusvarchar
opened_attimestamp
closed_attimestamp

order_item

Grain: one row per line item on an order

Check line.

ColumnTypeKeys
order_item_keybigintPK
order_keybigint
menu_item_keybigint
line_numberinteger
quantitydecimal
unit_pricedecimal
amountdecimal
seat_numbersmallint
special_instructionsvarchar
statusvarchar

order_item_modifier

Grain: one row per modifier applied to a line

Junction: modifiers chosen on an order line.

ColumnTypeKeys
order_item_modifier_keybigintPK
order_item_keybigint
modifier_keybigint
quantitysmallint
price_deltadecimal

kitchen_ticket

Grain: one row per kitchen ticket (KDS)

Kitchen display ticket.

ColumnTypeKeys
kitchen_ticket_keybigintPK
order_keybigint
ticket_numbervarcharBK
stationvarchar
fired_attimestamp
completed_attimestamp
statusvarchar

payment

Grain: one row per payment against an order

Tender record.

ColumnTypeKeys
payment_keybigintPK
order_keybigint
payment_numbervarcharBK
payment_methodvarchar
card_last_fourvarcharPII
amountdecimal
tip_amountdecimal
statusvarchar
transaction_referencevarchar
paid_attimestamp

ingredient

Grain: one row per inventory ingredient

Stock item.

ColumnTypeKeys
ingredient_keybigintPK
location_keybigint
ingredient_codevarcharBK
ingredient_namevarchar
unit_of_measurevarchar
unit_costdecimal
quantity_on_handdecimal
reorder_leveldecimal
is_allergenboolean

recipe

Grain: one row per ingredient used by a menu item

Junction: menu-item bill of materials.

ColumnTypeKeys
recipe_keybigintPK
menu_item_keybigint
ingredient_keybigint
quantitydecimal
unit_of_measurevarchar
is_optionalboolean

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • menu.location_key → location (many-to-one)
  • menu_item.menu_key → menu (many-to-one)
  • modifier.menu_item_key → menu_item (many-to-one)
  • dining_table.location_key → location (many-to-one)
  • staff.location_key → location (many-to-one)
  • order.location_key → location (many-to-one)
  • order.dining_table_key → dining_table (many-to-one)
  • order.staff_key → staff (many-to-one)
  • order_item.order_key → order (many-to-one)
  • order_item.menu_item_key → menu_item (many-to-one)
  • order_item_modifier.order_item_key → order_item (many-to-one)
  • order_item_modifier.modifier_key → modifier (many-to-one)
  • kitchen_ticket.order_key → order (many-to-one)
  • payment.order_key → order (many-to-one)
  • ingredient.location_key → location (many-to-one)
  • recipe.menu_item_key → menu_item (many-to-one)
  • recipe.ingredient_key → ingredient (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time