CS/DBMS
[Sequelize] `findAll` 옵션: `raw`와 `nest`는 언제 사용할까?
DandyNow
2025. 4. 28. 14:15
728x90
반응형
Sequelize findAll
옵션: raw
와 nest
는 언제 사용할까?
Node.js에서 Sequelize ORM을 사용하다 보면 데이터를 조회하는 findAll
메서드를 자주 사용하게 된다. 이때 raw: true
나 nest: true
같은 옵션들을 마주치게 되는데, 이 옵션들이 정확히 어떤 역할을 하고 언제 사용하는 것이 좋은지 정리해 보았다.
1. Sequelize findAll
의 기본 동작
기본적으로 findAll
메서드는 데이터베이스에서 조회한 결과를 Sequelize 모델 인스턴스(Instance)의 배열로 반환한다.
// 예시: User 모델 사용
const users = await models.User.findAll({
where: { status: 'active' }
});
// users 배열의 각 요소는 Sequelize 모델 인스턴스이다.
if (users.length > 0) {
console.log(users[0].name); // 인스턴스의 속성 접근
// await users[0].update({ name: 'newName' }); // 인스턴스 메서드 사용 가능
}
- 장점: 모델 인스턴스는 내장된
update
,destroy
,save
등의 유용한 메서드를 제공하며, 가상 필드나 연관 관계 메서드 접근이 용이하다. - 단점: 단순 데이터 조회가 목적일 경우, 인스턴스 생성에 따른 약간의 메모리 및 성능 오버헤드가 발생할 수 있다.
2. raw: true
옵션: 성능 최적화의 시작
조회한 데이터를 단순히 읽기용으로 사용하거나 다른 형태로 가공할 목적이라면, Sequelize 모델 인스턴스까지 만들 필요가 없을 수 있다. 이때 raw: true
옵션이 유용하다.
const activeUserNames = await models.User.findAll({
where: { status: 'active' },
attributes: ['name'], // 필요한 컬럼만 지정
raw: true, // <-- 여기!
});
// activeUserNames 배열의 각 요소는 순수 JavaScript 객체이다.
// 예: [ { name: '김일남' }, { name: '김이남' } ]
if (activeUserNames.length > 0) {
console.log(activeUserNames[0].name); // 객체의 속성 접근
// activeUserNames[0].update is not a function 오류 발생! (인스턴스 메서드 없음)
}
raw: true
: Sequelize가 모델 인스턴스를 생성하는 대신, 조회 결과를 순수한 JavaScript 객체(Plain JavaScript Object) 배열로 반환하도록 한다.- 장점: 모델 인스턴스 생성 비용이 없으므로, 특히 대량의 데이터를 조회할 때 성능 및 메모리 사용량 측면에서 이점이 있다. 조회한 데이터를 가공하여 API 응답으로 보내거나 다른 데이터 구조로 변환할 때 편리하다.
- 단점: 반환된 객체는 Sequelize 인스턴스 메서드(예:
update
,save
)를 가지고 있지 않다.
3. nest: true
옵션: JOIN 결과 구조화
nest: true
옵션은 주로 include
옵션을 사용하여 연관된 테이블을 함께 조회(JOIN)할 때, 그리고 raw: true
옵션과 함께 사용될 때 의미가 있다. JOIN된 결과를 중첩된 객체 형태로 만들어준다.
// 가정: User 모델은 Profile 모델과 1:1 관계 (User.hasOne(models.Profile))
// 1. raw: true 만 사용 (nest: false 와 동일)
const usersFlat = await models.User.findAll({
include: {
model: models.Profile,
attributes: ['bio']
},
attributes: ['id', 'name'],
where: { status: 'active' },
raw: true,
});
// 결과 예시 (평면적):
// [
// { id: 1, name: '김일남', 'Profile.bio': 'Developer' },
// { id: 2, name: '김이남', 'Profile.bio': 'Designer' }
// ]
// 2. raw: true 와 nest: true 함께 사용
const usersNested = await models.User.findAll({
include: {
model: models.Profile,
attributes: ['bio']
},
attributes: ['id', 'name'],
where: { status: 'active' },
raw: true,
nest: true, // <-- 여기!
});
// 결과 예시 (중첩적):
// [
// { id: 1, name: '김일남', Profile: { bio: 'Developer' } },
// { id: 2, name: '김이남이남', Profile: { bio: 'Designer' } }
// ]
nest: true
:include
와raw: true
가 함께 사용될 때, JOIN된 연관 모델의 속성들을 점(.
)으로 연결된 평면적인 키 대신, 중첩된 객체 안으로 구조화한다.- 주의:
include
옵션 없이 단일 테이블만 조회하거나,raw: true
옵션이 없다면nest: true
는 아무런 효과를 내지 못한다. 불필요하게 사용하면 코드를 혼란스럽게 만들 수 있다.
4. 언제 어떤 옵션을 사용해야 할까? (요약)
- 데이터 조회 후 바로 사용하거나 인스턴스 메서드가 필요할 때: 기본값 사용 (옵션 X)
- 단순 데이터 조회(읽기 전용)가 목적이고 성능이 중요할 때:
raw: true
사용 - JOIN된 데이터를 조회하고 그 결과를 중첩된 순수 객체로 받고 싶을 때:
include
+raw: true
+nest: true
사용 - JOIN된 데이터를 모델 인스턴스 형태로 다루고 싶을 때:
include
사용 (옵션 X 또는raw: false
) - JOIN이 없을 때:
nest: true
는 사용하지 않는다.
각 옵션의 정확한 역할을 이해하고 상황에 맞게 사용한다면, Sequelize를 더욱 효율적으로 활용하고 코드의 의도를 명확하게 전달할 수 있을 것이다.
728x90
반응형