Understanding Relationships in MySQL and Prisma
Introduction
In relational databases like MySQL, defining relationships between tables is essential for structuring data efficiently. There are three main types of relationships: One-to-One (1:1), One-to-Many (1:M), and Many-to-Many (M:N). Each type requires a specific table structure, foreign key constraints, and query approach.
In this article, we will explore:
- How to define relationships in MySQL with SQL table schemas.
- How to query related data using SQL.
- How to model the same relationships in Prisma ORM.
- How to retrieve related data using Prisma queries.
By the end, you’ll have a solid understanding of how to manage relational data efficiently with MySQL and Prisma. 🚀
1. Types of Relations in MySQL
In MySQL, relationships between tables are typically categorized into three main types:
- One-to-One (1:1)
- One-to-Many (1:M)
- Many-to-Many (M:N)
For each relation, I will explain:
- Table Schema in MySQL
- Querying the Relationship in SQL
- How to Define It in Prisma Schema
- Querying the Relationship in Prisma
- Example Output
2. One-to-One (1:1) Relationship
Example Scenario
A User can have one Profile, and a Profile belongs to only one User.
MySQL Table Schema
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE profiles ( id INT AUTO_INCREMENT PRIMARY KEY, bio TEXT, user_id INT UNIQUE, -- Ensures one-to-one relationship FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );
Querying in MySQL (Fetching User with Profile)
SELECT users.id, users.name, profiles.bio FROM users LEFT JOIN profiles ON users.id = profiles.user_id;
Example Output
id | name | bio |
---|---|---|
1 | John | Loves coding |
2 | Alice | Enjoys music |
Defining One-to-One in Prisma Schema
model User { id Int @id @default(autoincrement()) name String profile Profile? } model Profile { id Int @id @default(autoincrement()) bio String? user User @relation(fields: [userId], references: [id]) userId Int @unique }
Querying in Prisma
const userWithProfile = await prisma.user.findMany({ include: { profile: true } }); console.log(userWithProfile);
Example Output in Prisma
[ { "id": 1, "name": "John", "profile": { "bio": "Loves coding" } }, { "id": 2, "name": "Alice", "profile": { "bio": "Enjoys music" } } ]
3. One-to-Many (1:M) Relationship
Example Scenario
A User can have many Posts, but each Post belongs to only one User.
MySQL Table Schema
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE posts ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), content TEXT, user_id INT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );
Querying in MySQL (Fetching User with Posts)
SELECT users.id, users.name, posts.title FROM users LEFT JOIN posts ON users.id = posts.user_id;
Example Output
id | name | title |
---|---|---|
1 | John | MySQL Guide |
1 | John | Prisma Intro |
2 | Alice | Music Life |
Defining One-to-Many in Prisma Schema
model User { id Int @id @default(autoincrement()) name String posts Post[] } model Post { id Int @id @default(autoincrement()) title String content String? user User @relation(fields: [userId], references: [id]) userId Int }
Querying in Prisma
const usersWithPosts = await prisma.user.findMany({ include: { posts: true } }); console.log(usersWithPosts);
Example Output in Prisma
[ { "id": 1, "name": "John", "posts": [ { "title": "MySQL Guide", "content": "MySQL is great!" }, { "title": "Prisma Intro", "content": "Prisma is awesome!" } ] }, { "id": 2, "name": "Alice", "posts": [{ "title": "Music Life", "content": "I love music" }] } ]
4. Many-to-Many (M:N) Relationship
Example Scenario
A Student can enroll in many Courses, and a Course can have many Students.
MySQL Table Schema
CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE courses ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL ); CREATE TABLE enrollments ( student_id INT, course_id INT, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE, FOREIGN KEY (course_id) REFERENCES courses(id) ON DELETE CASCADE );
Querying in MySQL (Fetching Students with Courses)
SELECT students.name, courses.title FROM enrollments JOIN students ON enrollments.student_id = students.id JOIN courses ON enrollments.course_id = courses.id;
Example Output
name | title |
---|---|
John | Math 101 |
John | Physics 201 |
Alice | Math 101 |
Defining Many-to-Many in Prisma Schema
model Student { id Int @id @default(autoincrement()) name String courses Course[] @relation("Enrollments") } model Course { id Int @id @default(autoincrement()) title String students Student[] @relation("Enrollments") } model Enrollment { student Student @relation(fields: [studentId], references: [id]) studentId Int course Course @relation(fields: [courseId], references: [id]) courseId Int @@id([studentId, courseId]) }
Querying in Prisma
const studentsWithCourses = await prisma.student.findMany({ include: { courses: true } }); console.log(studentsWithCourses);
Example Output in Prisma
[ { "name": "John", "courses": [{ "title": "Math 101" }, { "title": "Physics 201" }] }, { "name": "Alice", "courses": [{ "title": "Math 101" }] } ]
5. Summary Table
Relationship | MySQL Schema | SQL Query | Prisma Schema | Prisma Query |
---|---|---|---|---|
One-to-One | user_id UNIQUE in second table | JOIN ON user_id | User has Profile? | include: { profile: true } |
One-to-Many | Foreign key in child table | JOIN ON user_id | User has Post[] | include: { posts: true } |
Many-to-Many | Junction table with two FKs | JOIN through junction | Student[] - Course[] | include: { courses: true } |
Conclusion
- MySQL uses foreign keys and junction tables to define relationships.
- Prisma uses a declarative schema to simplify relationship management.
- Querying relationships in Prisma is easy using
include
. - Output in Prisma is structured as JSON, making it easy to work with.
Top comments (0)