About Database Joins & Nest.Js
In SQL, a database join is an operation that allows us to combine data from two or more tables based on a related column between them. By using joins, we can avoid storing redundant data in a single table and instead distribute data across multiple tables to keep the structure clean and efficient. Different types of joins offer different ways to combine data, and each type affects the final result in a unique way.
조인(Join) 은 데이터베이스에서 두 개 이상의 테이블을 결합하여 원하는 데이터를 추출하는 SQL 연산이다. 데이터베이스는 여러 개의 테이블에 데이터를 분산하여 저장하는데, 이때 필요한 데이터를 한 테이블에 모두 저장하기보다는 여러 테이블로 나누어 저장함으로써 데이터 중복을 방지하고 구조를 간결하게 유지할 수 있다. 조인은 다음과 같은 다양한 유형으로 나눌 수 있으며, 각 조인 방법에 따라 결과가 다르게 나타난다.
1. INNER JOIN
INNER JOIN only returns rows where there is a match in both tables. It excludes rows where there’s no match, making it useful for retrieving only the intersecting data between tables.
SELECT A.column1, B.column2
FROM TableA AS A
INNER JOIN TableB AS B ON A.id = B.a_id;
Key Points
- Returns only the matching data between the tables.
- Efficient when we only need data that exists in both tables.
1. INNER JOIN
INNER JOIN 은 조인하는 두 테이블 간에 공통된 값을 가진 행만 결과로 반환한다. 두 테이블 모두에 일치하는 데이터가 있는 경우에만 결과로 표시되며, 일치하지 않는 데이터는 결과에서 제외 된다.
SELECT A.column1, B.column2
FROM TableA AS A
INNER JOIN TableB AS B ON A.id = B.a_id;
특징
- 교집합 역할을 하며, 일치하는 데이터가 있는 행만 반환.
- 데이터 중복 방지에 좋지만, 모든 일치하지 않는 데이터는 버려짐.
2. LEFT JOIN (or LEFT OUTER JOIN)
LEFT JOIN returns all rows from the left table and the matched rows from the right table. If there’s no match, it returns NULL for columns from the right table.
SELECT A.column1, B.column2
FROM TableA AS A
LEFT JOIN TableB AS B ON A.id = B.a_id;
Key Points
- Returns all rows from the left table, including those without a match.
- Useful when we want all data from the left table, regardless of matches.
2. LEFT JOIN (또는 LEFT OUTER JOIN)
LEFT JOIN 은 조인의 기준이 되는 왼쪽 테이블의 모든 행을 포함하고, 오른쪽 테이블에 일치하는 데이터가 있는 경우에만 그 데이터를 반환한다. 오른쪽 테이블에 일치하는 데이터가 없으면 NULL 값이 표시된다.
SELECT A.column1, B.column2
FROM TableA AS A
LEFT JOIN TableB AS B ON A.id = B.a_id;
특징
- 왼쪽 테이블의 모든 데이터를 포함하므로 결과에서 일부 NULL 값이 포함될 수 있음.
- 비어 있는 경우에도 왼쪽 테이블의 모든 데이터가 유지됨.
3. RIGHT JOIN (or RIGHT OUTER JOIN)
RIGHT JOIN is the opposite of LEFT JOIN. It returns all rows from the right table and the matched rows from the left table. If there’s no match, it returns NULL for columns from the left table.
SELECT A.column1, B.column2
FROM TableA AS A
RIGHT JOIN TableB AS B ON A.id = B.a_id;
Key Points
- Returns all rows from the right table, including those without a match.
- Useful when we want all data from the right table, regardless of matches.
3. RIGHT JOIN (또는 RIGHT OUTER JOIN)
RIGHT JOIN 은 LEFT JOIN 의 반대 개념이다. 오른쪽 테이블의 모든 행을 기준으로 하여, 일치하는 왼쪽 테이블의 데이터만 결합한다. 오른쪽 테이블에 일치하지 않는 데이터가 있는 경우, NULL 값이 들어간다.
SELECT A.column1, B.column2
FROM TableA AS A
RIGHT JOIN TableB AS B ON A.id = B.a_id;
특징
- 오른쪽 테이블의 모든 데이터를 포함.
- 오른쪽 테이블 기준으로 결합되며, 왼쪽에 없는 데이터는 NULL 로 채워짐.
4. FULL OUTER JOIN
FULL OUTER JOIN returns all rows from both tables, including those without matches. When there is no match, NULL values are included for columns from the other table.
SELECT A.column1, B.column2
FROM TableA AS A
FULL OUTER JOIN TableB AS B ON A.id = B.a_id;
Key Points
- Combines LEFT JOIN and RIGHT JOIN, returning all data.
- Useful when we want to see all data from both tables, even if there are no matches.
4. FULL OUTER JOIN
FULL OUTER JOIN 은 LEFT JOIN과 RIGHT JOIN 의 합집합이다. 두 테이블 모두의 데이터를 포함하며, 일치하지 않는 데이터는 NULL 값으로 표시된다.
SELECT A.column1, B.column2
FROM TableA AS A
FULL OUTER JOIN TableB AS B ON A.id = B.a_id;
특징
- 양쪽 테이블의 모든 데이터를 포함하여 NULL 값이 포함될 가능성이 높음.
- 데이터의 모든 경우를 확인하고자 할 때 유용.
5. CROSS JOIN
CROSS JOIN returns the Cartesian product of the two tables, combining each row from one table with every row from the other. This join creates all possible combinations of rows, which is often not desired in real applications but can be useful in specific scenarios.
SELECT A.column1, B.column2
FROM TableA AS A
CROSS JOIN TableB AS B;
Key Points
- Returns every possible row combination.
- Use with caution as it can produce very large result sets.
5. CROSS JOIN
CROSS JOIN 은 두 테이블의 모든 행을 조합하여 결과를 생성한다. 조인의 기준이 없기 때문에 모든 가능한 행의 조합이 포함된 “카티션 곱(Cartesian Product)”을 반환한다. 일반적으로 사용되지 않지만, 모든 조합을 확인하고자 할 때 사용 가능하다.
SELECT A.column1, B.column2
FROM TableA AS A
CROSS JOIN TableB AS B;
특징
- 모든 가능한 행의 조합을 반환.
- 각 테이블의 모든 행과 행을 결합하므로 결과가 매우 많아질 수 있음.
Implementing Joins in NestJS
To implement joins in NestJS, we use TypeORM to set up entities with relationships and then create queries through the repository pattern. Here’s a demonstration using INNER JOIN and LEFT JOIN in NestJS, though the same approach applies to other joins.
1. Define Entities in NestJS
For this example, we’ll work with two entities: User
and Profile
.
user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn } from 'typeorm';
import { Profile } from './profile.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile;
}
profile.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
@Column()
avatar: string;
}
NestJS에서 조인 구현하기
NestJS 에서 데이터베이스 조인을 사용하려면 TypeORM 을 사용하여 엔티티 간 관계를 설정하고, 리포지토리 패턴을 통해 쿼리를 작성할 수 있다. 아래 예시는 INNER JOIN 과 LEFT JOIN 을 기반으로 작성하겠지만, 다른 조인도 비슷한 방식으로 설정할 수 있다.
1. NestJS 에서 엔티티(Entity) 설정하기
두 개의 엔티티인 User
와 Profile
을 예제로 들어 보자.
user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn } from 'typeorm';
import { Profile } from './profile.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile;
}
profile.entity.ts
//profile.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
@Column()
avatar: string;
}
2. Create Join Queries in the Repository
Using TypeORM’s QueryBuilder
, we can write custom join queries.
INNER JOIN Example
This query uses INNER JOIN to combine User
and Profile
data.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
async findAllUsersWithProfiles() {
return this.userRepository
.createQueryBuilder('user')
.innerJoinAndSelect('user.profile', 'profile')
.getMany();
}
}
In this code, innerJoinAndSelect
joins user
and profile
tables using INNER JOIN and retrieves matching records.
LEFT JOIN Example
To include users without a profile, use leftJoinAndSelect
.
async findAllUsersWithOptionalProfiles() {
return this.userRepository
.createQueryBuilder('user')
.leftJoinAndSelect('user.profile', 'profile')
.getMany();
}
3. Set up the Controller to Call the Service
Finally, let’s set up a controller to expose this data via an API endpoint.
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async getAllUsers() {
return await this.userService.findAllUsersWithProfiles();
}
}
2. TypeORM 리포지토리에서 JOIN 쿼리 작성하기
TypeORM의 QueryBuilder
를 사용하여 원하는 조인 쿼리를 작성할 수 있다.
INNER JOIN 예제
User
엔티티와 Profile
엔티티를 INNER JOIN 하여 사용자와 프로필 정보를 함께 가져오는 예제.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
async findAllUsersWithProfiles() {
return this.userRepository
.createQueryBuilder('user')
.innerJoinAndSelect('user.profile', 'profile')
.getMany();
}
}
위 코드에서는 innerJoinAndSelect
메서드를 사용하여 user
테이블과 profile
테이블을 INNER JOIN
하고, 해당 데이터를 모두 가져온다.
LEFT JOIN 예제
LEFT JOIN
을 사용해 profile
이 없는 사용자도 포함하여 가져오려면 leftJoinAndSelect
메서드를 사용하면 된다.
async findAllUsersWithOptionalProfiles() {
return this.userRepository
.createQueryBuilder('user')
.leftJoinAndSelect('user.profile', 'profile')
.getMany();
}
3. NestJS에서 Service를 호출하여 Controller 작성하기
이제, 위의 서비스를 Controller
에서 호출하여 사용할 수 있다.
user.controller.ts
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async getAllUsers() {
return await this.userService.findAllUsersWithProfiles();
}
}
Example Output for Join Code in NestJS
When calling the GET /users
endpoint, you’ll get a JSON response that includes both User and Profile data. Suppose our database contains the following:
- User table:
{ id: 1, name: 'John Doe', email: 'john@example.com' }
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' } - Profile table:
{ id: 1, bio: 'Software Developer', avatar: 'avatar1.png', userId: 1 }
With a GET request to /users
, we’ll receive:
[
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"profile": {
"id": 1,
"bio": "Software Developer",
"avatar": "avatar1.png"
}
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane@example.com",
"profile": null
}
]
NestJS 조인 코드 실행 결과 예시
이제 GET /users
엔드포인트를 호출하면, User와 Profile을 조인한 결과를 JSON으로 확인할 수 있다. 예를 들어, 데이터베이스에 다음과 같은 데이터가 있는 경우:
User
테이블:{ id: 1, name: 'John Doe', email: 'john@example.com' }
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }Profile
테이블:{ id: 1, bio: 'Software Developer', avatar: 'avatar1.png', userId: 1 }
GET /users
호출 시 다음과 같은 JSON 데이터를 얻게 된다:
[
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"profile": {
"id": 1,
"bio": "Software Developer",
"avatar": "avatar1.png"
}
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane@example.com",
"profile": null
}
]
1. INNER JOIN — Linking Customer and Order Data
Scenario:
In an e-commerce application, INNER JOIN is commonly used to view specific orders placed by a customer. For instance, by joining the Customers
and Orders
tables, we can retrieve the details of each product a customer has ordered.
Example:
- Goal: Retrieve a list of all products ordered by a specific customer.
SELECT Customers.name, Orders.order_id, Orders.product
FROM Customers
INNER JOIN Orders ON Customers.id = Orders.customer_id
WHERE Customers.id = 1;
- Explanation:
INNER JOIN
only includes rows whereCustomers.id
matchesOrders.customer_id
. This ensures we only get orders that exist for the customer, keeping the data clean and avoiding duplicates.
1. INNER JOIN — 고객과 주문 데이터 연관
상황:
전자상거래 애플리케이션에서 특정 고객의 주문 내역을 보고 싶을 때 사용된다. 예를 들어, 고객 정보가 있는 Customers
테이블과 주문 정보가 있는 Orders
테이블을 결합하여 특정 고객이 주문한 상품의 상세 내역을 조회할 수 있다.
예제:
- 목표: 고객의 ID를 기준으로 그들이 주문한 모든 상품의 리스트를 가져오기.
SELECT Customers.name, Orders.order_id, Orders.product
FROM Customers
INNER JOIN Orders ON Customers.id = Orders.customer_id
WHERE Customers.id = 1;
- 설명:
INNER JOIN
은Customers
와Orders
테이블의customer_id
가 일치하는 경우에만 데이터를 가져온다. 이 방법으로 고객이 실제 주문한 내역만 확인할 수 있어 중복 없이 깨끗한 데이터를 제공한다.
2. LEFT JOIN — Displaying Posts and Comments
Scenario:
In a social media or blog application, LEFT JOIN is useful when displaying posts along with their comments. LEFT JOIN includes posts that may not have any comments, ensuring no posts are left out.
Example:
- Goal: Retrieve posts and their comments, showing posts even if they have no comments.
SELECT Posts.title, Comments.content
FROM Posts
LEFT JOIN Comments ON Posts.id = Comments.post_id;
- Explanation:
LEFT JOIN
returns all rows from thePosts
table and matches rows from theComments
table where possible. Posts without comments show NULL for theComments
columns, allowing us to display posts with or without comments.
2. LEFT JOIN — 게시물과 댓글 데이터
상황:
SNS 나 블로그 애플리케이션에서 게시물(Post)과 해당 댓글(Comment)을 함께 보여줄 때 자주 사용된다. 댓글이 없는 게시물도 표시할 수 있어 유용하다.
예제:
- 목표: 게시물과 댓글을 함께 가져와 댓글이 없는 게시물도 표시.
SELECT Posts.title, Comments.content
FROM Posts
LEFT JOIN Comments ON Posts.id = Comments.post_id;
설명: LEFT JOIN
을 사용하면 Posts
테이블의 모든 게시물이 포함되며, 댓글이 없는 게시물은 Comments
데이터가 NULL로 표시된다. 이를 통해 댓글이 없는 게시물도 쉽게 표시할 수 있다.
3. RIGHT JOIN — Viewing Company and Employee Data
Scenario:
In an organization management system, we might want to list employees and their respective companies. RIGHT JOIN is useful here when we want all employees listed, even if some are not linked to a specific company.
Example:
- Goal: Retrieve a list of employees with their associated company, if any.
SELECT Employees.name, Company.name AS company_name
FROM Employees
RIGHT JOIN Company ON Employees.company_id = Company.id;
- Explanation:
RIGHT JOIN
includes all rows from theCompany
table and matches rows from theEmployees
table where there is a match. Employees without an associated company appear with NULL forcompany_name
.
3. RIGHT JOIN — 회사와 직원 데이터
상황:
회사 데이터를 다루는 애플리케이션에서 회사(Company)와 직원(Employee) 데이터를 결합할 때 사용된다. 모든 직원에 대한 정보를 보고 싶지만, 일부 직원이 회사 정보와 연결되지 않는 경우가 있다면 유용하다.
예제:
- 목표: 모든 직원 리스트를 가져오되, 소속 회사 정보도 포함.
SELECT Employees.name, Company.name AS company_name
FROM Employees
RIGHT JOIN Company ON Employees.company_id = Company.id;
- 설명:
RIGHT JOIN
을 사용하여 직원 정보를 모두 가져오고, 소속 회사가 없는 직원은 회사 정보가 NULL 로 표시된다. 이를 통해 조직에 소속되지 않은 직원도 포함해 데이터를 확인할 수 있다.
4. FULL OUTER JOIN — Showing Students and Courses Data
Scenario:
In a school management system, FULL OUTER JOIN can be useful to view all students and courses regardless of whether a student is enrolled in a particular course. This join type allows us to get a full view of both tables.
Example:
- Goal: Retrieve all students and all courses, regardless of enrollment.
SELECT Students.name, Courses.course_name
FROM Students
FULL OUTER JOIN Courses ON Students.course_id = Courses.id;
Explanation: FULL OUTER JOIN
includes all rows from both Students
and Courses
, showing any courses without students or any students without courses, with NULL values where there is no match.
4. FULL OUTER JOIN — 학생과 과목 데이터
상황:
학교 관리 시스템에서 학생(Student)과 수강 과목(Course) 데이터를 가져올 때, 학생과 수강 과목 데이터를 모두 보고자 할 때 사용된다. 특정 과목을 듣는 학생과 모든 과목 리스트를 보고자 할 때 유용하다.
예제:
- 목표: 수강 여부와 상관없이 학생과 과목 리스트 모두를 가져오기.
SELECT Students.name, Courses.course_name
FROM Students
FULL OUTER JOIN Courses ON Students.course_id = Courses.id;
설명: FULL OUTER JOIN
을 사용하면 학생과 과목에 대한 모든 데이터가 포함된다. 수강하지 않은 과목이나 특정 과목을 듣지 않는 학생에 대한 정보도 포함할 수 있다.
5. CROSS JOIN — Generating Product Combinations
Scenario:
In recommendation systems or combination scenarios, CROSS JOIN is used. For example, a fashion store might want to show all possible combinations of tops and bottoms to customers for style recommendations.
Example:
- Goal: Generate all possible combinations of tops and bottoms for recommendations.
SELECT Tops.name AS top_name, Bottoms.name AS bottom_name
FROM Tops
CROSS JOIN Bottoms;
Explanation: CROSS JOIN
creates every possible combination of Tops
and Bottoms
, allowing for complete style recommendations by combining all items in both tables.
5. CROSS JOIN — 다중 조합 생성
상황:
추천 시스템이나 모든 조합을 보고자 하는 경우. 예를 들어, 패션 쇼핑몰에서 모든 가능한 상의와 하의의 조합을 만들고 싶을 때 사용된다.
예제:
- 목표: 모든 상의와 하의의 조합을 생성하여 고객에게 추천하기.
SELECT Tops.name AS top_name, Bottoms.name AS bottom_name
FROM Tops
CROSS JOIN Bottoms;
설명: CROSS JOIN
은 Tops
와 Bottoms
테이블의 모든 행을 조합한다. 결과는 모든 상의와 하의의 조합을 포함하여 고객에게 다양한 코디 추천을 할 수 있게 해준다.
Understanding Database Joins: Performance and Real-World Alternatives
When working with relational databases, joins are a fundamental way to combine data from multiple tables. However, while joins are powerful, they can become a performance bottleneck in large-scale applications. In this post, we’ll explore how joins impact performance, when to avoid them, and effective alternative strategies used in real-world applications.
데이터베이스 조인 이해하기: 성능과 실무에서의 대안
관계형 데이터베이스를 다룰 때 조인(Join) 은 여러 테이블의 데이터를 결합하기 위한 기본적인 방법이다. 하지만 조인은 강력한 기능인 동시에 대규모 애플리케이션에서는 성능 문제의 원인이 될 수 있다. 이번 포스트에서는 조인이 성능에 미치는 영향과 조인을 피해야 할 상황 그리고 실무에서 사용하는 대체 전략을 살펴보자.
Performance Impacts of Joins
Joins are relatively heavy SQL operations, especially as the size of the tables grows. As tables increase in size, the time required for join operations escalates, affecting response time and potentially overloading the database.
Some key factors that influence join performance include:
- Table Size: Larger tables require more memory and CPU resources.
- Index Availability: Joining on columns without indexes is slower since the database must scan entire tables.
- Join Type: Different join types (INNER JOIN, LEFT JOIN, FULL OUTER JOIN, etc.) have varying impacts on performance.
- Server Resources: Limited CPU and memory can hinder large join operations.
Because of these factors, many high-traffic applications approach joins cautiously and often opt for alternative methods to maintain performance.
조인이 성능에 미치는 영향
조인은 SQL 연산 중에서도 비교적 무거운 작업에 속해, 테이블 크기가 커질수록 성능 저하를 초래할 수 있다. 조인을 사용할 때 걸리는 시간이 증가하게 되며, 이는 응답 속도와 데이터베이스 부하에 영향을 미친다.
조인의 성능에 영향을 미치는 요인은 다음과 같다:
- 테이블 크기: 큰 테이블일수록 CPU와 메모리 사용량이 크게 증가한다.
- 인덱스 유무: 조인 대상 컬럼에 인덱스가 없으면 데이터베이스가 전체 테이블을 스캔해야 하므로 성능이 저하된다.
- 조인 유형: INNER JOIN, LEFT JOIN, FULL OUTER JOIN 등 조인 방식에 따라 성능에 차이가 있다.
- 서버 자원: 메모리와 CPU 자원이 충분하지 않으면 대규모 조인 작업에서 병목현상이 발생할 수 있다.
이런 이유로 대규모 트래픽이 있는 애플리케이션에서는 조인을 신중하게 사용하는 편이 좋고, 종종 조인을 대체할 수 있는 방법을 찾기도 한다.
Why Joins Are Avoided in Real-World Applications
In real-world applications where performance is critical, it’s common to minimize or avoid joins. Two main approaches often replace or reduce joins:
- Allowing Data Redundancy (Denormalization)
- This approach involves duplicating data across tables to reduce the need for joins, sacrificing strict normalization for the sake of speed. Instead of storing
address_id
in theuser
table and joining with anaddress
table, you might store address details directly in theuser
table. - Although this goes against the principles of normalization, it significantly improves performance by avoiding joins on frequently accessed data.
2. Using NoSQL Databases
- NoSQL databases, like MongoDB, are designed with flexible schemas that support embedding related data, eliminating the need for joins. Instead of linking
user
andaddress
data through joins, we can nest the address within the user document, allowing faster, single-query retrieval. - By consolidating related data within a single document, NoSQL enables efficient data retrieval without joins, making it a strong choice for real-time or high-traffic applications.
실무에서 조인을 피하는 이유
실제 대규모 애플리케이션에서는 성능 최적화를 위해 조인을 최소화하거나 피하는 것이 일반적이다. 조인 대신 사용할 수 있는 주요 대체 접근 방식은 다음 두 가지이다:
- 데이터 중복 허용 (Denormalization)
- 데이터를 필요한 만큼 중복하여 저장해 조인을 피하는 방법이다. 데이터베이스 정규화 원칙을 벗어나지만, 자주 함께 조회되는 데이터를 중첩하여 저장하면 조인 없이 빠르게 조회할 수 있다.
- 예를 들어,
user
테이블에address_id
를 두고 주소 테이블과 조인하는 대신,address
정보를user
테이블에 바로 저장할 수 있다. 이를 통해 데이터를 조회할 때 여러 테이블을 조인할 필요가 없어져 조회 성능이 향상된다.
2. NoSQL 사용
- MongoDB 같은 NoSQL 데이터베이스는 스키마가 유연해 중첩된 형태로 데이터를 저장할 수 있다. 이를 통해 조인을 피할 수 있고, 한 번의 쿼리로 관련 데이터를 모두 조회할 수 있다.
- 예를 들어,
user
와address
데이터를 함께 저장해두면, 조인이 필요 없고 한 번에 조회할 수 있어 성능적으로 유리하다.
Summary of Join Alternatives
- Data Redundancy (Denormalization): Storing frequently queried data together to minimize joins.
- NoSQL Databases: Leveraging document-based storage, like MongoDB, to nest data and avoid joins.
- Caching: Storing frequently accessed data in cache systems like Redis can reduce the need for repeated database joins.
조인을 피하기 위한 대체 전략 요약
- 데이터 중복 저장 (Denormalization): 자주 함께 조회되는 데이터를 함께 저장해 조인을 최소화 한다.
- NoSQL 데이터베이스 사용: MongoDB와 같은 NoSQL 을 사용해 데이터를 유연하게 관리하고, 필요한 데이터를 한 번에 가져올 수 있도록 설계한다.
- 캐싱 (Caching): Redis 같은 캐시 저장소에 자주 조회되는 데이터를 저장하여 데이터베이스 부하를 줄인다.