Spotify Database Design
Last updated
Last updated
In this practice, we will be creating a database for my personal favorite! music app, Spotify. To do this, we will need to define the tables for each component and the relationships among them. Let's go over the main components we see when we run Spotify:
Users
Artists
Albums
Tracks
Playlists
Followers
Likes
Now that we've defined the major components it is time to create the tables and the data we will be storing in them. We can categorize the table in three groups: user-related, artist-related, and association:
User Related Tables
users: Stores data regarding the users, including their names, emails, passwords, dates of birth, and profile images
playlists: Stores data about user-created playlists, including image, playlist's name and its description, and user id that will serve as a foreign key to link it to the users table.
Artist Related Tables
artists: Stores data about the artists, including their names, genre, and images.
albums: Stores data regarding albums, including name, release year, image, and an artist id that will relate it it to the artists table.
tracks: Stores data about the tracks like name, duration, and the file path, and the album id as a foreign key to link the tracks to the album table.
Association Tables
playlists_and_tracks: shows us the connection between playlists and tracks.
follows: shows us the relation between users and artists.
likes: Stores relationship info between the users and the tracks they 'liked', including date and time, user id and track id.
Needless to say, each table has their own unique identifiers such as Primary Keys.
Now that we have our tables, it is now time to establish the relationships among tables. There are three main relationships in a database:
one-to-one.
one-to-many.
many-to-many
IBM's summary is a great resource to check https://www.ibm.com/docs/en/mam/7.6.0?topic=structure-database-relationships
In our design, we will have the last two relationships among our tables: one-to-many, or many-to-many:
One-to-Many:
Users and Playlists: One user may have none, one, or multiple playlists
Artists and Albums: One artist may have none, one, or multiple albums
Albums and Tracks: One album may have none, one, or multiple tracks
Many-to-Many:
Playlists and Tracks (playlists_and_tracks): One playlist can have any number of tracks, and one track can be part of any number of playlists.
Users and Artists (follows): One user may be following any number of artists, and one artist may be followed by any number of users.
Users and Tracks (likes): One user may like any number of tracks, and one track may be liked by any number of users.
Through these tables and relationships, we can readily access and manipulate data pertaining to users, artists, albums, tracks, playlists, followers, and likes.
Let us display the tables' structures and create them simultaneously with the following queries in PostgreSQL:
The following diagram shows the table structures and the relationships among them:
Let us see the characteristics of our entities in data model:
User: Represents a user, and includes information like user ID, name, email, password, date of birth, and image.
Artist: Represents an artist, and includes information like artist ID, name, genre, and image.
Album: Represents an album, and includes information like album ID, artist ID, name, release date, and image.
Track: Represents a track, and includes information such as track ID, album ID, name, duration, and path.
Playlist: Represents a user's playlist, and includes information like playlist ID, user ID, name, description and image.
Playlist_Track: Represents the relationship between a playlist and a track, includes information like playlist ID, track ID, and order.
Follow: Represents the relationship between a user and an artist, where a user can follow any number of artists and an artist can be followed by any number of users.
Like: Represents the relationship between a user and a track, where a user may like any number of tracks, and a track may be liked by any number of users.
Congratulations! By defining our data model that shows the relationships among the tables that we have described in the table structures and relationships sections, we have concluded our (basic) Spotify database design. By designing our database this way, we have normalized the data that we will be storing in the database, i.e. eliminated any prospect redundant data entry and enabled an improved data retrieval and manipulation.
As we know Spotify offers two types of subscriptions:
Freemium (Free with Ads)
Premium (Paid with No Ads)
The premium subscriptions/plan also consists of four different packages based on users' needs and budget: Premium Individual, Premium Student, Premium Duo, Premium Family.
The above database design was a simplified version of Spotify and didn't consist of information regarding to the users' subscription types. In this part, we will be including this information to our tables and updating our database design. Because the premium plans requires payment we will be adding tables regarding payments as well.
Adding subscription/user type to the users
table is fairly simple. Let us start by giving every user a default subscription/user type of 'freemium':
It is now time to define what 'freemium' package or paid premium plans offer to listeners. We know that Spotify offers different features, some of which can be seen below, for different subscription types, and those features may be subjected to the changes or plans may have additional features in the feature.
Over 80 million songs
✓
✓
Podcasts and audiobooks
✓
✓
Travel abroad with your music
For up to 14 days.
✓
Pick and play any track on mobile
Available on select playlists.
✓
Play songs in any order
✓
Ad free music
✓
Download music
✓
Download podcasts
✓
✓
Highest music quality
✓
Therefore it is best to first create a separate table that includes only these features:
Now, let us incorporate the freemium and premium plans and create an association table to connect features to their respective packages:
Now that we have the packages along with their features, we can assign packages to the subscibers:
By adding the tables above, we have now defined two different subscription types, including freemium and premium and assigned different features to listeners. It is time for us to add the last feature which is the payments information for the premium users.
We will create a table to store all payment information:
By adding the payment information to our system we have concluded our Spotify Database Design, and our data model became as follows:
Once again, our design is by no means the ultimate system and can be improved further by adding different entities like recommendations, notifications, etc.