Hotel Booking Database Schema database schema
The Hotel Booking Database Schema database schema is a DB Planner template with 16 tables, 134 columns and 23 relationships, free to use. Core tables include amenities, booking_guests, booking_room_nights, booking_rooms. It can be opened as an interactive diagram or exported as PostgreSQL, MySQL, or MSSQL DDL.
- Tables
- 16
- Columns
- 134
- Relationships
- 23
- Category
- Marketplace
- Exports
- DBML, SQL, C#
- Price
- Free
What this schema models
A hotel reservation and property management database schema that gets the two decisions right which make or break every booking system. 16 tables, 13 enums and 23 relationships covering properties, room types, amenities, physical rooms, rate plans, cancellation policies, a per-night rate and availability calendar, guests, bookings, payments, housekeeping and verified reviews. DECISION 1 — AVAILABILITY IS PER ROOM TYPE PER NIGHT Guests book a room TYPE, not a specific door. A specific room is assigned at check-in via booking_rooms.assigned_room_id, which stays null until then. Pinning a guest to room 402 six months in advance is exactly what causes the endless reshuffles that hotel systems are notorious for. rate_calendar holds one row per room type per rate plan per night, carrying both rooms_available and rate_cents, so a single indexed table answers both "what is free" and "what does it cost" — which is why availability search stays fast. DECISION 2 — A STAY IS PRICED AS THE SUM OF ITS NIGHTS booking_room_nights stores one row per night with the rate frozen at booking time. Rates move daily; a confirmed booking must not. Totals on bookings are snapshots rolled up from those rows, so any later change to rate_calendar can never rewrite what a guest was quoted. OTHER DETAILS WORTH STEALING - Dates are LOCAL calendar dates, not UTC instants, which is why properties carries a timezone alongside check_in_time and check_out_time. - Non-refundable at a lower price is a rate plan, not a discount — and it carries its own cancellation policy with an hours threshold and a penalty type. - One booking, many rooms: a family taking two rooms is one reservation with two booking_rooms rows. - booking_guests records who actually occupies each room, which many jurisdictions legally require a hotel to capture, separately from whoever paid. - Deposits, balances, incidentals and refunds are all separate rows in payments distinguished by type. Never net them into one figure. - Housekeeping closes the loop: a room is not sellable again until its departure clean is completed. - reviews is unique on booking_id, so only a real completed stay can leave one. That single constraint is the entire anti-fake-review mechanism. - Money in minor units as integers. Never floats. WHAT YOU GET Clean DBML that imports straight into DB Planner, plus a laid-out board with cards colour-coded by zone — property and rooms, rates and availability, guests, bookings, money, operations and trust — with sticky notes explaining each decision, and every table carrying its own Note. Postgres-flavoured types that port cleanly to MySQL or SQL Server. Useful for developers building a hotel PMS, booking engine or channel manager, students needing a realistic hotel reservation ER diagram, and anyone modelling date-range inventory for the first time.
Tables (16)
| Table | Columns |
|---|---|
| amenities | 4 |
| booking_guests | 3 |
| booking_room_nights | 4 |
| booking_rooms | 9 |
| bookings | 17 |
| cancellation_policies | 6 |
| guests | 9 |
| housekeeping_tasks | 8 |
| payments | 9 |
| properties | 16 |
| rate_calendar | 8 |
| rate_plans | 10 |
| reviews | 12 |
| room_type_amenities | 2 |
| room_types | 11 |
| rooms | 6 |
Relationships (23)
booking_guests.booking_room_id references booking_rooms.idmany to onebooking_guests.guest_id references guests.idmany to onebooking_room_nights.booking_room_id references booking_rooms.idmany to onebooking_rooms.assigned_room_id references rooms.idmany to onebooking_rooms.booking_id references bookings.idmany to onebooking_rooms.rate_plan_id references rate_plans.idmany to onebooking_rooms.room_type_id references room_types.idmany to onebookings.primary_guest_id references guests.idmany to onebookings.property_id references properties.idmany to onecancellation_policies.property_id references properties.idmany to onehousekeeping_tasks.room_id references rooms.idmany to onepayments.booking_id references bookings.idmany to onerate_calendar.rate_plan_id references rate_plans.idmany to onerate_calendar.room_type_id references room_types.idmany to onerate_plans.cancellation_policy_id references cancellation_policies.idmany to onerate_plans.property_id references properties.idmany to onereviews.booking_id references bookings.idmany to onereviews.guest_id references guests.idmany to onereviews.property_id references properties.idmany to oneroom_type_amenities.amenity_id references amenities.idmany to oneroom_type_amenities.room_type_id references room_types.idmany to oneroom_types.property_id references properties.idmany to onerooms.room_type_id references room_types.idmany to one
How to use this template
- Open the diagram to see the tables and how they relate.
- Copy it into your workspace. You get your own editable copy.
- Export it as PostgreSQL, MySQL, or MSSQL DDL, or as C# models.
Frequently asked questions
- What is in the Hotel Booking Database Schema schema?
- 16 tables and 23 relationships, across 134 columns. The table names and the full relationship list are shown on this page.
- Can I export it to PostgreSQL or MySQL?
- Yes. Every DB Planner template exports as DBML, PostgreSQL, MySQL, or MSSQL DDL, and as C# models.
- Is this template free?
- Yes. You can open it in the browser without an account, and copy it into your own workspace with a free DB Planner account.
- Can I change it after copying it?
- Yes. A copy is yours: you can rename tables, add columns, and export it. Changes the author makes later do not affect your copy.