A multi-tenant event ticketing schema where one organisation sells tickets to its own events. The accounts table is the tenant root, and most operational tables carry a redundant account_id index alongside their real parent FK to scope every query to one tenant.
What this Attendize schema covers
Events with venue, branding, and sale windows
Ticket types with price, quantity, and access gating
Orders, line items, and individual attendees
Custom checkout questions for buyers and attendees
Per-account payment gateways and Stripe credentials
Affiliate referral tracking and daily event stats
A few decisions the diagram can't show:
One purchase is described three ways: order_items (price snapshot), the ticket_order pivot, and one attendees row per ticket holder.
reserved_tickets holds inventory mid-checkout, keyed by session_id with an expires timestamp; checkout_timeout_after sets the window.
Hidden ticket types (tickets.is_hidden) unlock only through event_access_codes via the ticket_event_access_code pivot.
date_formats and datetime_formats are duplicate lookups, but accounts.datetime_format_id points at date_formats; datetime_formats is orphaned.
Orders track state as booleans (is_cancelled, is_refunded, is_deleted) alongside order_status_id, not one status column.
Good fork target for self-hosted ticketing with per-account gateways. Gateway settings sit in a serialized config column and Stripe tokens in plaintext on accounts, so treat both as secrets.
Self-hosted event ticketing and management — Attendize is an open-source, self-hosted platform that lets event organisers sell tickets and manage attendees without paying third-party service fees.