2024-06-21

Understanding Database Relationships

Introduction

When designing a database, understanding the types of relationships between tables is crucial. These relationships define how data in one table is related to data in another. In this post, we'll explore three main types of relationships: one-to-one, one-to-many, and many-to-many.

data-model

Terminology

  • Table: A collection of related data organized in rows and columns.
  • Primary Key (PK): A unique identifier for each record in a table. A column is marked as a primary key to ensure data integrity.
  • Foreign Key (FK): A column in a table that references the primary key of another table.
  • Join Table: A table used to establish a many-to-many relationship between two tables.

Relationship Types

These relationships are related to Structured Query Language (SQL) databases but same concepts can be applied to other types of databases as well with some variations.

One-to-One Relationships

A one-to-one relationship is established when a single record in one table is linked to a single record in another table, using a foreign key to reference the primary key of the other table.

Example: Users and UserDetails

In this scenario, each user has a unique set of details. The purpose of creating a separate table for user details is to avoid redundancy and to keep the database normalized.

**Users table:**

| id  | userName | email | passwordHash  |
| --- | -------- | ----- | ------------- |
| 0   | -        | -     | -             |
| 1   | -        | -     | -             |

**UserDetails table:**

| id  | user_id | fullName  | birthDate  | address |
| --- | ------- | --------- | ---------- | ------- |
| 0   | 0       | -         | -          | -       |
| 1   | 1       | -         | -          | -       |

In this example, the user_id column in the UserDetails table references the id column in the Users table, creating a one-to-one relationship. Each user has only one set of details.

One-to-Many Relationships

A one-to-many relationship occurs when a single record in one table is associated with multiple records in another table. This is achieved by using a foreign key in the "many" table to reference the primary key in the "one" table.

Example: Users and Authentications

Here, each user can have multiple authentication tokens, representing logins from different devices.


**Users table:**

| id  | username | email | passwordHash  |
| --- | -------- | ----- | ------------- |
| 0   | -        | -     | -             |
| 1   | -        | -     | -             |

**Authentications table:**

| id  | user_id | token | expiresAt  |
| --- | ------- | ----- | ---------- |
| 0   | 1       | -     | -          |
| 1   | 1       | -     | -          |
| 2   | 2       | -     | -          |

In this case, the user_id column in the Authentications table references the id column in the Users table, establishing a one-to-many relationship. A single user can have multiple authentication records.

Many-to-Many Relationships

A many-to-many relationship occurs when multiple records in one table are associated with multiple records in another table. To represent this relationship, a join table is created to connect the two tables through foreign keys.

Example: Users and Roles

Here, a user can have multiple roles, and each role can be assigned to multiple users.

**Users table:**

| id  | username | email | passwordHash  |
| --- | -------- | ----- | ------------- |
| 0   | -        | -     | -             |
| 1   | -        | -     | -             |

**Roles table:**

| id  | name     |
| --- | -------- |
| 0   | -        |
| 1   | -        |

**UserRoles table:**

| id  | user_id | role_id |
| --- | ------- | ------- |
| 0   | 1       | 1       |
| 1   | 1       | 2       |
| 2   | 2       | 1       |
| 3   | 2       | 0       |

In this scenario, the UserRoles table has user_id and role_id columns that reference the id columns in the Users and Roles tables, respectively.

Conclusion

By mastering these types of relationships, you can build databases that accurately reflect the real-world scenarios they're designed to support. This will make your applications easier to maintain. So dive in, practice these concepts, and see how they can improve your database designs.

Diagram as code reference

Following is a diagram as code that represents the relationships discussed in this post and can be utilized in eraser.io.

users [icon: data, color: blue] {
  id string pk
  userName string
  email string
  passwordHash string
}

userDetails [icon: data, color: yellow] {
  id string pk
  fullName string
  birthDate string
  adress string
}

authentications [icon: data, color: green] {
  id string pk
  token string
  expiresAt number
}

roles [icon: data, color: purple] {
  id string pk
  name string
}

userDetails.user_id - users.id
users.id < authentications.user_id
roles.id <> users.id