<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alexey Makhotkin</title>
    <description>The latest articles on DEV Community by Alexey Makhotkin (@databasedesignbook).</description>
    <link>https://dev.to/databasedesignbook</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4105038%2F7bf64ad2-0b81-4fcb-9771-11082827a2fa.png</url>
      <title>DEV Community: Alexey Makhotkin</title>
      <link>https://dev.to/databasedesignbook</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/databasedesignbook"/>
    <language>en</language>
    <item>
      <title>Database Modeling of a Music Marketplace. Part 1</title>
      <dc:creator>Alexey Makhotkin</dc:creator>
      <pubDate>Tue, 29 Sep 2026 07:03:03 +0000</pubDate>
      <link>https://dev.to/databasedesignbook/database-modeling-of-a-music-marketplace-part-1-1o08</link>
      <guid>https://dev.to/databasedesignbook/database-modeling-of-a-music-marketplace-part-1-1o08</guid>
      <description>&lt;p&gt;I'd like to discuss database modeling of a big music marketplace — the website Discogs.com. It's one of the largest databases of physical music media: CDs, vinyl, cassettes, and so on. It covers millions of artists, albums, and releases.&lt;/p&gt;

&lt;p&gt;We're going to build the &lt;strong&gt;logical model&lt;/strong&gt;, following the approach from my &lt;a href="https://databasedesignbook.com/" rel="noopener noreferrer"&gt;&lt;em&gt;Database Design Book&lt;/em&gt;&lt;/a&gt;. That means cataloging three things: &lt;strong&gt;anchors, attributes, and links&lt;/strong&gt;. For now, we won't talk about the physical schema — tables, indexes, query optimization. We'll focus purely on the business of selling physical music, and what you need to specify for implementation, as if we were building a Discogs clone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Logical Schema
&lt;/h2&gt;

&lt;p&gt;We’ll keep the entire schema in three Google Docs tables: anchors, attributes and links.  Most of the schema describes the logical level.  Logical level is independent from a specific database server.&lt;/p&gt;

&lt;p&gt;The columns on the right side, “&lt;em&gt;Table name&lt;/em&gt;”, “&lt;em&gt;Physical column/type&lt;/em&gt;”, “&lt;em&gt;Table or column names&lt;/em&gt;” specify the physical level.  We will talk about that much later in the series, because first we need to agree on what we need to implement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anchors
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;ID example&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table name&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;45467&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;bands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;br&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Attributes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Question&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Logical data type&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Example value&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical column&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical type&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;What is the name of this Band?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;em&gt;“Pink Floyd”&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;bands.name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;VARCHAR(128)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;br&gt;&lt;br&gt;
&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor1 : Anchor2&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Cardi-nality&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Sentences&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table or column names&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band : Album&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 : N&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Band has &lt;em&gt;several&lt;/em&gt; Albums&lt;br&gt;&lt;br&gt;An Album was recorded by &lt;em&gt;only one&lt;/em&gt; Band&lt;/td&gt;
&lt;td&gt;&lt;code&gt;albums.band_id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Exploring Discogs
&lt;/h2&gt;

&lt;p&gt;Let's look at a well-known artist: &lt;a href="https://www.discogs.com/artist/45467-Pink-Floyd" rel="noopener noreferrer"&gt;Pink Floyd&lt;/a&gt;. They have 314 releases at the time of writing, with many versions of each. There's a lot of detail here, but I'll show how to handle it incrementally — start with small pieces, design the basic functionality, and then add detail as needed.&lt;/p&gt;

&lt;p&gt;Discogs has a huge &lt;strong&gt;content catalog&lt;/strong&gt;: releases and track lists. It’s the main part of the website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92ygy9jl57sn19wj99cd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92ygy9jl57sn19wj99cd.jpg" alt="Artist page" width="800" height="771"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It also has a &lt;strong&gt;social-network layer&lt;/strong&gt; — users can mark that they own an album, that they want to purchase a copy, they can rate stuff, and write reviews. Their first album has more than 100,000 people who own it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqd3bgu3f5co7dx8ati9l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqd3bgu3f5co7dx8ati9l.jpg" alt="Social network block" width="694" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, there's a &lt;strong&gt;marketplace&lt;/strong&gt;: you can buy and sell music. For this particular album there are more than 2500 listings, from sellers all over the world, in all sorts of formats and item qualities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpqgyntsmstll9zh3d9rl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpqgyntsmstll9zh3d9rl.jpg" alt="Browsing music catalog page" width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll start with the simplest part of the schema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Artists / Bands
&lt;/h3&gt;

&lt;p&gt;Looking at the URL — &lt;code&gt;https://www.discogs.com/artist/45467-Pink-Floyd&lt;/code&gt; — is often useful when thinking about database design. The artist page has a name, photos (there can be many), links to related sites, a list of members (some crossed out), and name variations.&lt;/p&gt;

&lt;p&gt;Looking at the release list for this artist, we see &lt;strong&gt;format&lt;/strong&gt;, &lt;strong&gt;label&lt;/strong&gt;, &lt;strong&gt;country&lt;/strong&gt;, and &lt;strong&gt;year&lt;/strong&gt; columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Format&lt;/strong&gt;: Album, Vinyl, LP, CD, Cassette, Reissue, Remastered, etc.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Label&lt;/strong&gt;: EMI, Columbia, etc.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country&lt;/strong&gt;: US, UK, Europe (yes, "Europe" is listed as a country), and further down the list, combinations like Australia &amp;amp; New Zealand, or Singapore &amp;amp; Malaysia.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Year&lt;/strong&gt;: just a list of years — straightforward.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll figure out how to model each of these.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vlwrrj8sv7wmgz24ogq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vlwrrj8sv7wmgz24ogq.jpg" alt="Albums catalog" width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Albums
&lt;/h3&gt;

&lt;p&gt;Taking one album — &lt;em&gt;A Saucerful of Secrets&lt;/em&gt; — it has a cover photo (again, potentially many), a name, a track list, credits (credits will get complicated, since this is music — more on that later), extensive notes, formats as before, and links to other versions of the same release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzwl5dlkeip7b0wxu9mr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzwl5dlkeip7b0wxu9mr.jpg" alt="Album page" width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Releases vs. Masters
&lt;/h3&gt;

&lt;p&gt;Looking at the URL for a specific pressing: &lt;code&gt;https://www.discogs.com/release/730906-Pink-Floyd-A-Saucerful-Of-Secrets&lt;/code&gt;. This one is a vinyl LP, stereo, published by a specific label, with a catalog number, country of release, series, genre, style, track list, track credits, involved companies, and links to other versions (e.g., pressed in France or the UK). There are also recommendations and user reviews/comments.&lt;/p&gt;

&lt;p&gt;You can see the release's sales history — sold for as low as €11 and as high as €158 — and you can add it to your collection. There are also videos and other extras.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F071ivut2ahfc6dmiogof.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F071ivut2ahfc6dmiogof.jpg" alt="Release page" width="799" height="903"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This specific pressing is called a &lt;strong&gt;release&lt;/strong&gt;. The broader work it belongs to — with its own distinct ID in the URL — is called a &lt;strong&gt;master&lt;/strong&gt;. A master can have many releases published across different years: 34 releases in '68, 16 in '94, and so on — essentially, some release of a given master comes out almost every year.&lt;/p&gt;

&lt;h2&gt;
  
  
  First cut at logical schema
&lt;/h2&gt;

&lt;p&gt;Let’s start building the logical schema by filling in the tables. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ll skip the “table name” column for now — physical tables will be discussed much later in the series.  We must have a reliable logical model before venturing into table design strategies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that we will sometimes be intentionally naive and jump to conclusions prematurely. This is to demonstrate how modeling mistakes are handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bands and albums
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Band&lt;/strong&gt; is our first anchor — there are many bands, new ones get created, and so on — a clear anchor.  Later we may discover that this is not a very good name, but let’s begin with something.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;ID example&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table name&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;45467&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Anchors keep track of IDs.  Here we have an example of an ID that we took from the Pink Floyd URL: we know that it’s a number.&lt;/p&gt;

&lt;p&gt;We scroll down the artist page and we see that there are many albums released by Pink Floyd.  So, &lt;strong&gt;Album&lt;/strong&gt; is our next anchor. In the Discogs URL scheme they call it "master." We'll start by calling it "album" and see if that name holds up — in database design, you often start with one name and later realize it was the wrong choice. We'll see whether that happens here.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;ID example&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table name&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;45467&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Album&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;10352&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Attributes
&lt;/h4&gt;

&lt;p&gt;Attributes belong to anchors.  They contain the actual information.&lt;/p&gt;

&lt;p&gt;We document attributes as questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Question&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Logical data type&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Example value&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical column&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical type&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;What is the name of this Band?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;em&gt;“Pink Floyd”&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Album&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;What is the name of this Album?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;em&gt;“Saucerful of Secrets”&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Again, skipping the physical column/type for now.) We can leave most other band/album details aside for a moment — a name is enough to get started.&lt;/p&gt;

&lt;h4&gt;
  
  
  Links
&lt;/h4&gt;

&lt;p&gt;Links (also called "relationships" in classical terminology) connect two anchors. We document them as semi-formalized sentences using either "several" or "only one":&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor1 : Anchor2&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Cardi-nality&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Sentences&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table or column names&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Band : Album&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 : N&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Band has &lt;em&gt;several&lt;/em&gt; Albums&lt;br&gt;&lt;br&gt;An Album was recorded by &lt;em&gt;only one&lt;/em&gt; Band&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;(Convention: when cardinality is one-to-many, the "one" side anchor is listed first.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These sentences look almost like plain English but follow a strict structure — they name two anchors and use one of two fixed phrases ("several" or "only one"). Reading them aloud, and having others read them, helps confirm whether they actually match business reality. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(Note: We already know this will need revisiting — collaborations mean an album can have several bands. We'll get there. For now, we handle the most common case, then extend the model as needed. The nice part is that revising this document, before any code exists, is cheap.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Releases
&lt;/h3&gt;

&lt;p&gt;Looking at an early release of the album: URL is &lt;code&gt;https://www.discogs.com/release/1382387-Pink-Floyd-A-Saucerful-Of-Secrets&lt;/code&gt;, with a lot more detail — label, format, country, release date, genre, style, track list, and credits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrdz16fl8qpjhnapxhpl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrdz16fl8qpjhnapxhpl.jpg" alt="Release page" width="800" height="841"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see what we can see here.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Release name&lt;/strong&gt;: inherited from the album — no need to duplicate it as a new attribute. (Or are we a bit naive here?)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format&lt;/strong&gt;: a comma-separated list of multiple values — since an attribute must be single-valued, this can't be an attribute as-is. We discuss formats later in the series.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country&lt;/strong&gt;: also not a simple attribute — later it will become its own anchor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Release date&lt;/strong&gt;: this &lt;em&gt;is&lt;/em&gt; a straightforward attribute.  But first we need to define the anchor:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;ID example&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table name&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;1382387&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And now the attribute:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Question&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Logical data type&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Example value&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical column&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical type&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;When was this Release released?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;date&lt;/td&gt;
&lt;td&gt;&lt;em&gt;1968-06-29&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Labels
&lt;/h3&gt;

&lt;p&gt;Clicking into a label — Columbia — its URL is &lt;code&gt;https://www.discogs.com/label/1866-Columbia&lt;/code&gt;. Columbia Records is described as the oldest brand name in recorded sound. The label page has a profile, parent label, sub-labels, contact info, links, and a list of releases — a quarter of a million releases published under this label. There are also reviews (of what exactly, we'll find out later).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frbljrs6pl5w2lbp2l6xi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frbljrs6pl5w2lbp2l6xi.jpg" alt="Label page" width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Label&lt;/strong&gt; is another anchor — there are many labels, they can be counted, and new ones can be created.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;ID example&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table name&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Label&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;1866&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Attributes of Label:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Question&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Logical data type&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Example value&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical column&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Physical type&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Label&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;What is the name of this Label?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;em&gt;“Columbia”&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most attributes at this stage are conceptually very simple — "everything has a name" — but it's worth carefully entering all the simple stuff now, because it pays off once things get more complicated (and with music, they will, quickly — and it'll be fun).&lt;/p&gt;

&lt;h4&gt;
  
  
  More links
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;Anchor1 : Anchor2&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Cardi-nality&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Sentences&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;Table or column names&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Album : Release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 : N&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An Album can have &lt;em&gt;several&lt;/em&gt; Releases&lt;br&gt;&lt;br&gt; A Release belongs to &lt;em&gt;only one&lt;/em&gt; Album&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Label : Release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 : N&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Label can publish &lt;em&gt;several&lt;/em&gt; Releases&lt;br&gt;&lt;br&gt; A Release can be published by &lt;em&gt;only one&lt;/em&gt; Label&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cardinality is arguably the most important — and hardest to fix later — piece of the model. That's why we write these sentences out and read them aloud: to catch cases where they don't actually match reality.&lt;/p&gt;

&lt;p&gt;Spoiler ahead: as we browse more of the catalog we may find out that the &lt;strong&gt;Label : Release&lt;/strong&gt; link may not be an accurate representation of business requirements.  It’s very common to uncover such complications as you study more cases from the real world.&lt;/p&gt;

&lt;p&gt;The advantage of catching this now is that revising a document is trivial — we haven't written any code yet, we didn’t even create any database tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where we've gotten to
&lt;/h2&gt;

&lt;p&gt;We're setting aside credits and track lists for now — those will come in the follow up posts, along with the rest of the content catalog. After that, we'll cover the social-network side (users, collections, reviews) and then the commercial side (buying and selling).&lt;/p&gt;

&lt;p&gt;So far we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 anchors (Band, Album, Release, Label)
&lt;/li&gt;
&lt;li&gt;4 simple attributes (names and release date)
&lt;/li&gt;
&lt;li&gt;3 links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discogs.com is genuinely complex.  I’ve been using it for 20 years, there is lots of stuff visible to the user.  But there is also a huge backoffice system that underlies it, with lots and lots of functionality that is necessary for operations.&lt;/p&gt;

&lt;p&gt;My rough guess is that modeling the entirety of Discogs' functionality might come out to a couple hundred anchors, a couple of times as many attributes, and again a couple hundred or so links. We'll see how that prediction holds up as the series continues.&lt;/p&gt;

&lt;p&gt;In the second part we’ll revisit bands, discuss tracklists and images, and talk more about recording labels.&lt;/p&gt;

&lt;p&gt;Thank you for reading.  This approach to database modeling is explained in more detail in my &lt;strong&gt;“&lt;a href="https://databasedesignbook.com/" rel="noopener noreferrer"&gt;Database Design Book&lt;/a&gt;”&lt;/strong&gt;, published last year.  It’s short (~150 pages), and to the point.&lt;/p&gt;

&lt;p&gt;P. S. If you prefer watching YouTube, here is a playlist from my channel: &lt;a href="https://youtube.com/playlist?list=PL1MPVszm5-apdoFvLfnrNw3X6zgxNhmWL&amp;amp;si=3Bny8a4lNKow3iwp" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PL1MPVszm5-apdoFvLfnrNw3X6zgxNhmWL&amp;amp;si=3Bny8a4lNKow3iwp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P. P. S. While I work on this series, you can read a previous tutorial: &lt;a href="https://kb.databasedesignbook.com/posts/google-calendar/" rel="noopener noreferrer"&gt;Database Design for Google Calendar&lt;/a&gt;, published in 2024.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Database Design Book
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://databasedesignbook.com/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foplblkfeednxtpkmkhiz.jpg" alt="Database Design Book cover" width="800" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>tutorial</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
