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.
- 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)
| Table | Columns |
|---|---|
| events | 11 |
| hold_items | 6 |
| holds | 6 |
| order_fees | 6 |
| order_items | 11 |
| orders | 15 |
| organizer_members | 4 |
| organizers | 6 |
| payments | 7 |
| performance_seats | 8 |
| performance_sections | 6 |
| performances | 9 |
| price_tiers | 5 |
| promo_codes | 11 |
| refund_items | 3 |
| refunds | 9 |
| scans | 10 |
| seat_maps | 5 |
| seat_rows | 4 |
| seats | 7 |
| sections | 6 |
| ticket_prices | 4 |
| ticket_transfers | 10 |
| ticket_types | 10 |
| tickets | 10 |
| users | 6 |
| venues | 8 |
Relationships (56)
events.organizer_id references organizers.idmany to onehold_items.hold_id references holds.idmany to onehold_items.performance_seat_id references performance_seats.idmany to onehold_items.performance_section_id references performance_sections.idmany to onehold_items.ticket_type_id references ticket_types.idmany to oneholds.user_id references users.idmany to oneorder_fees.order_id references orders.idmany to oneorder_fees.order_item_id references order_items.idmany to oneorder_items.order_id references orders.idmany to oneorder_items.performance_id references performances.idmany to oneorder_items.performance_seat_id references performance_seats.idmany to oneorder_items.performance_section_id references performance_sections.idmany to oneorder_items.price_tier_id references price_tiers.idmany to oneorder_items.ticket_type_id references ticket_types.idmany to oneorders.hold_id references holds.idmany to oneorders.promo_code_id references promo_codes.idmany to oneorders.user_id references users.idmany to oneorganizer_members.organizer_id references organizers.idmany to oneorganizer_members.user_id references users.idmany to onepayments.order_id references orders.idmany to oneperformance_seats.hold_id references holds.idmany to oneperformance_seats.performance_id references performances.idmany to oneperformance_seats.price_tier_id references price_tiers.idmany to oneperformance_seats.seat_id references seats.idmany to oneperformance_sections.performance_id references performances.idmany to oneperformance_sections.price_tier_id references price_tiers.idmany to oneperformance_sections.section_id references sections.idmany to oneperformances.event_id references events.idmany to oneperformances.seat_map_id references seat_maps.idmany to oneprice_tiers.event_id references events.idmany to onepromo_codes.event_id references events.idmany to onepromo_codes.organizer_id references organizers.idmany to onepromo_codes.unlocks_ticket_type_id references ticket_types.idmany to onerefund_items.order_item_id references order_items.idmany to onerefund_items.refund_id references refunds.idmany to onerefunds.order_id references orders.idmany to onerefunds.payment_id references payments.idmany to onerefunds.requested_by references users.idmany to onescans.performance_id references performances.idmany to onescans.scanned_by references users.idmany to onescans.ticket_id references tickets.idmany to oneseat_maps.venue_id references venues.idmany to oneseat_rows.section_id references sections.idmany to oneseats.row_id references seat_rows.idmany to onesections.seat_map_id references seat_maps.idmany to oneticket_prices.price_tier_id references price_tiers.idmany to oneticket_prices.ticket_type_id references ticket_types.idmany to oneticket_transfers.from_ticket_id references tickets.idmany to oneticket_transfers.from_user_id references users.idmany to oneticket_transfers.to_ticket_id references tickets.idmany to oneticket_transfers.to_user_id references users.idmany to oneticket_types.event_id references events.idmany to onetickets.holder_user_id references users.idmany to onetickets.order_item_id references order_items.idmany to onetickets.performance_id references performances.idmany to onetickets.replaces_ticket_id references tickets.idmany to one
How to use this template
- Open the ER diagram to see the tables and how they relate.
- Copy it into your workspace. You get your own editable copy, in DBML.
- 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.