Music Streaming ER diagram and database schema

The Music Streaming database schema is a DB Planner template with 26 tables, 177 columns and 40 relationships, free to use. Core tables include artists, audio_files, availability_windows, devices. It can be opened as an interactive ER diagram or exported as PostgreSQL, MySQL, or SQL Server DDL.

ER diagram of the Music Streaming database schema, showing 26 tables and their relationships
FIG. 1: entity relationship diagram, 26 tables
Tables
26
Columns
177
Relationships
40
Category
Social
Exports
DBML, SQL, C#
Price
Free

What this schema models

A complete music streaming app database design, modeled on how streaming services actually separate catalog, rights and listening: 26 tables, 11 enums and 40 relationships covering artists, releases, tracks, credits and genres, labels, territory availability windows and audio encodings, users, plans, per-country prices and family subscriptions, playlists, collaborators, follows and saved library items, devices and the play event stream, and daily play counts feeding pro-rata royalty pools and statements. THE FOUR DESIGN RULES 1. A RELEASE is not a TRACK. A track is a recording with an ISRC; a release (album, single, EP or compilation) has a UPC and a tracklist with disc and position. The same song on the single and on the album is one track, with one play count and one royalty line. 2. Credits are rows with roles. Many artists link to a track as main, featured, producer, writer, composer or remixer, in display order. "A feat. B" is rendered from those rows, never stored as a string, so the featured artist page finds the track too. 3. Play events are an append-only firehose; reports read rollups. play_events is partitioned monthly by played_at, never updated, and copies the territory and plan tier at play time. A daily job rolls it up into play_counts per track, territory and tier, which charts, artist dashboards and royalty runs read instead. 4. Royalties are pooled, then split by share of streams. Each month the net revenue of a territory and tier forms a pool; the per-stream rate is revenue times the rights share divided by qualified streams (30 seconds or more), and each label statement is its qualified streams times that rate. DETAILS WORTH STEALING - Playlists order tracks by a lexicographic rank, so dragging track 900 to the top of a 1,000-track playlist rewrites one row; entries have their own id because a track can appear twice. - Follows and library saves use one nullable foreign key per target plus a check constraint, so every follow is an enforced foreign key instead of a generic target_id. - Availability windows are per release, territory and access tier, and a takedown ends a window instead of deleting the release, so play history survives. - Audio files are one row per encoding, with codec, bitrate, loudness for volume normalization and a preview flag; a CDN serves the bytes. - Duo and family plans have members, with a partial unique index allowing one current plan per user; prices are per country and versioned, and a subscription keeps the price it was sold at. - unique_listeners in the daily rollup is flagged as not summable across days, a classic bug in monthly listener reports. WHAT YOU GET Clean DBML that imports directly into DB Planner, and a laid-out board with zones color-coded and framed: listening, users and subscriptions, library and social, catalog, rights and media, and play counts and royalties. Every table carries a note. Postgres-flavoured types that port cleanly to MySQL or SQL Server. Useful for developers building a music or audio streaming app, and for students who need a realistic music streaming ER diagram for a DBMS project. This is a schema design reference; real royalty deals, publishing rights and licensing terms vary widely and belong in your own business logic.

Tables (26)

Tables in the Music Streaming Database Schema schema and how many columns each has
TableColumns
artists10
audio_files10
availability_windows6
devices6
follows6
genres3
labels5
library_saves5
plan_prices7
play_counts7
play_events12
playlist_collaborators3
playlist_tracks6
playlists10
release_artists3
release_tracks4
releases12
royalty_pools10
royalty_statements9
subscription_members4
subscription_plans7
subscriptions10
track_credits4
track_genres2
tracks8
users8

Relationships (40)

  • audio_files.track_id references tracks.id many to one
  • availability_windows.release_id references releases.id many to one
  • devices.user_id references users.id many to one
  • follows.followed_artist_id references artists.id many to one
  • follows.followed_playlist_id references playlists.id many to one
  • follows.followed_user_id references users.id many to one
  • follows.follower_id references users.id many to one
  • genres.parent_id references genres.id many to one
  • labels.parent_label_id references labels.id many to one
  • library_saves.release_id references releases.id many to one
  • library_saves.track_id references tracks.id many to one
  • library_saves.user_id references users.id many to one
  • plan_prices.subscription_plan_id references subscription_plans.id many to one
  • play_counts.track_id references tracks.id many to one
  • play_events.device_id references devices.id many to one
  • play_events.track_id references tracks.id many to one
  • play_events.user_id references users.id many to one
  • playlist_collaborators.playlist_id references playlists.id many to one
  • playlist_collaborators.user_id references users.id many to one
  • playlist_tracks.added_by references users.id many to one
  • playlist_tracks.playlist_id references playlists.id many to one
  • playlist_tracks.track_id references tracks.id many to one
  • playlists.owner_user_id references users.id many to one
  • release_artists.artist_id references artists.id many to one
  • release_artists.release_id references releases.id many to one
  • release_tracks.release_id references releases.id many to one
  • release_tracks.track_id references tracks.id many to one
  • releases.label_id references labels.id many to one
  • royalty_statements.label_id references labels.id many to one
  • royalty_statements.royalty_pool_id references royalty_pools.id many to one
  • subscription_members.subscription_id references subscriptions.id many to one
  • subscription_members.user_id references users.id many to one
  • subscriptions.owner_user_id references users.id many to one
  • subscriptions.plan_price_id references plan_prices.id many to one
  • subscriptions.subscription_plan_id references subscription_plans.id many to one
  • track_credits.artist_id references artists.id many to one
  • track_credits.track_id references tracks.id many to one
  • track_genres.genre_id references genres.id many to one
  • track_genres.track_id references tracks.id many to one
  • tracks.label_id references labels.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 Music Streaming database schema?
26 tables and 40 relationships, across 177 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.