Event Ticketing ER diagram and database schema

The Event Ticketing database schema is a DB Planner template with 27 tables, 203 columns and 56 relationships, free to use. Core tables include events, hold_items, holds, order_fees. It can be opened as an interactive ER diagram or exported as PostgreSQL, MySQL, or SQL Server DDL.

ER diagram of the Event Ticketing database schema, showing 27 tables and their relationships
FIG. 1: entity relationship diagram, 27 tables
Tables
27
Columns
203
Relationships
56
Category
Marketplace
Exports
DBML, SQL, C#
Price
Free

What this schema models

A complete event ticketing system database design, built for the moment thousands of people press buy at once: 27 tables, 16 enums and 56 relationships covering organizers and staff, venues and seat maps (sections, rows and seats), events and performances, ticket types and price tiers, per-performance seat and general admission inventory, expiring cart holds, orders with frozen prices and fees, promo codes, payments and itemized refunds, tickets with unique barcodes, transfers and append-only door scans. THE FOUR DESIGN RULES 1. Inventory is per PERFORMANCE, one row per seat. performance_seats holds every sellable seat of every performance. Claiming seats is one conditional UPDATE (only where the seat is available or its hold has expired), and if fewer rows change than were requested, the transaction rolls back. The database decides who got the seat, so two buyers can never both win it; a partial unique index on order items is a second guard. 2. Holds expire by timestamp, not by a cleanup job. A cart stamps hold_expires_at on its seats, and an expired hold is simply claimable by the next buyer. A sweeper can tidy up for reporting, but correctness never depends on it running. 3. General admission is a counter with a CHECK. performance_sections stores capacity and sold_count with CHECK (sold_count <= capacity). A GA claim locks that one row, subtracts quantities in unexpired holds and inserts its hold item, so the last place cannot be sold twice even if application code is wrong. 4. An ORDER ITEM is a sale; a TICKET is a credential. Price, fees and refunds attach to the order item and are frozen at checkout. The ticket carries the barcode, and a transfer voids it and issues a new ticket with a new barcode, so a screenshot of the old one fails at the door. DETAILS WORTH STEALING - Seat maps are venue configurations (end stage, in the round), and seats carry x/y coordinates plus accessible and obstructed-view flags for drawing the map. - Prices are a matrix: ticket type (Adult, Child, VIP) by price tier (Orchestra A, Balcony C), and a seat can move to a different tier per performance for weekend pricing. - Killed seats (camera positions, sightlines) and house holds are statuses on the performance inventory, never deletions from the map. - Promo codes are case-insensitive, capped by a redemption counter with a CHECK, and can unlock hidden ticket types for presales. - refund_items make partial refunds exact: return one ticket of four and only that one is covered, with fee refundability decided at sale. - Scans record every read, rejects included, keeping the device clock and the server receipt time apart, because door scanners work offline and sync later. WHAT YOU GET Clean DBML that imports directly into DB Planner, and a laid-out board with zones color-coded and framed: accounts and organizers, venues and seat maps, events and pricing, inventory and holds, orders and payments, and tickets and entry. Every table carries a note. Postgres-flavoured types that port cleanly to MySQL or SQL Server. Useful for developers building a box office, ticketing platform or event app, and for students who need a realistic event ticketing system ER diagram for a DBMS project. This is a schema design reference; taxes, consumer refund rules and payment processing belong in your own business logic.

Tables (27)

Tables in the Event Ticketing Database Schema schema and how many columns each has
TableColumns
events11
hold_items6
holds6
order_fees6
order_items11
orders15
organizer_members4
organizers6
payments7
performance_seats8
performance_sections6
performances9
price_tiers5
promo_codes11
refund_items3
refunds9
scans10
seat_maps5
seat_rows4
seats7
sections6
ticket_prices4
ticket_transfers10
ticket_types10
tickets10
users6
venues8

Relationships (56)

  • events.organizer_id references organizers.id many to one
  • hold_items.hold_id references holds.id many to one
  • hold_items.performance_seat_id references performance_seats.id many to one
  • hold_items.performance_section_id references performance_sections.id many to one
  • hold_items.ticket_type_id references ticket_types.id many to one
  • holds.user_id references users.id many to one
  • order_fees.order_id references orders.id many to one
  • order_fees.order_item_id references order_items.id many to one
  • order_items.order_id references orders.id many to one
  • order_items.performance_id references performances.id many to one
  • order_items.performance_seat_id references performance_seats.id many to one
  • order_items.performance_section_id references performance_sections.id many to one
  • order_items.price_tier_id references price_tiers.id many to one
  • order_items.ticket_type_id references ticket_types.id many to one
  • orders.hold_id references holds.id many to one
  • orders.promo_code_id references promo_codes.id many to one
  • orders.user_id references users.id many to one
  • organizer_members.organizer_id references organizers.id many to one
  • organizer_members.user_id references users.id many to one
  • payments.order_id references orders.id many to one
  • performance_seats.hold_id references holds.id many to one
  • performance_seats.performance_id references performances.id many to one
  • performance_seats.price_tier_id references price_tiers.id many to one
  • performance_seats.seat_id references seats.id many to one
  • performance_sections.performance_id references performances.id many to one
  • performance_sections.price_tier_id references price_tiers.id many to one
  • performance_sections.section_id references sections.id many to one
  • performances.event_id references events.id many to one
  • performances.seat_map_id references seat_maps.id many to one
  • price_tiers.event_id references events.id many to one
  • promo_codes.event_id references events.id many to one
  • promo_codes.organizer_id references organizers.id many to one
  • promo_codes.unlocks_ticket_type_id references ticket_types.id many to one
  • refund_items.order_item_id references order_items.id many to one
  • refund_items.refund_id references refunds.id many to one
  • refunds.order_id references orders.id many to one
  • refunds.payment_id references payments.id many to one
  • refunds.requested_by references users.id many to one
  • scans.performance_id references performances.id many to one
  • scans.scanned_by references users.id many to one
  • scans.ticket_id references tickets.id many to one
  • seat_maps.venue_id references venues.id many to one
  • seat_rows.section_id references sections.id many to one
  • seats.row_id references seat_rows.id many to one
  • sections.seat_map_id references seat_maps.id many to one
  • ticket_prices.price_tier_id references price_tiers.id many to one
  • ticket_prices.ticket_type_id references ticket_types.id many to one
  • ticket_transfers.from_ticket_id references tickets.id many to one
  • ticket_transfers.from_user_id references users.id many to one
  • ticket_transfers.to_ticket_id references tickets.id many to one
  • ticket_transfers.to_user_id references users.id many to one
  • ticket_types.event_id references events.id many to one
  • tickets.holder_user_id references users.id many to one
  • tickets.order_item_id references order_items.id many to one
  • tickets.performance_id references performances.id many to one
  • tickets.replaces_ticket_id references tickets.id many to one

How to use this template

  1. Open the ER diagram to see the tables and how they relate.
  2. Copy it into your workspace. You get your own editable copy, in DBML.
  3. Export it as PostgreSQL, MySQL, or SQL Server DDL, or as C# models.

The copy opens in DB Planner’s ER diagram tool, with the schema as text in the DBML editor beside it. Have a database already? Turn its SQL into an ER diagram instead.

Frequently asked questions

What is in the Event Ticketing database schema?
27 tables and 56 relationships, across 203 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, as PostgreSQL, MySQL, or SQL Server 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.