Prisma 메소드 정리 (Prisma 사용 시 헷갈리는 리턴 타입 & 무료 DB 최적화 가이드)
2026. 1. 13. 23:06ㆍSTUDY
반응형
findUnique -- 단일 조회 (Read)
@id 또는 @unique가 설정된 필드로 단 하나의 레코드를 조회
| 데이터가 있으면 | 데이터가 없으면 | 실행중 에러 발생 |
| Object (객체) | null | Error 던짐 (throw) |
const item = await db.test.findUnique({
where: { id: "clx123..." },
include: { comments: true } // 관계 데이터 포함 가능
});
findFirst -- 단일 조회 (Read)
- 조건에 맞는 데이터 중 가장 첫 번째 레코드를 조회
- 고유값이 아닌 필드(예: display_id, status)로 검색할 때 유용
| 데이터가 있으면 | 데이터가 없으면 | 실행중 에러 발생 |
| Object (객체) | null | Error 던짐 (throw) 조건이 유니크 제약조건이 아닐 경우(예: 없는 필드로 검색) 컴파일 타임 에러가 발생 |
const latest = await db.test.findFirst({
where: { status: "COMPLETED" },
orderBy: { created_at: "desc" }
});
findMany -- 다중 조회 (Read Many)
- 조건에 맞는 모든 레코드를 리스트로 리턴
- skip, take, cursor를 이용해 페이지네이션을 구현할 때 필수
| 데이터가 있으면 | 데이터가 없으면 | 실행중 에러 발생 |
| [{...},{...}...] | [] -- 빈배열 | Error 던짐 (throw) |
const list = await db.test.findMany({
where: {
price: { gte: 10000 }, // 10,000원 이상 (Greater Than or Equal)
},
take: 10, // 10개만 호출 (무료 DB 쿼리 절약)
select: { id: true, display_id: true } // 필요한 필드만 선택
});
create -- 생성
새로운 레코드를 하나 생성
| 성공 | 대상 데이터가 없을 때 | 실행중 에러 발생 |
| 생성된 Object | Error 던짐 (중복 키 등) |
const newItem = await db.test.create({
data: {
display_id: "REC-001",
price: 5000,
status: "PENDING",
storeId: "store_abc"
}
});
update -- 수정
특정 조건(id 등 고유값)을 만족하는 하나의 레코드를 수정
| 성공 | 대상 데이터가 없을 경우 | 실행중 에러 발생 |
| 수정된 Object | 조건에 맞는 데이터가 없으면 에러(P2025) | Error 던짐 |
✓ P2025 에러
"An operation failed because it depends on one or more records that were required but not found."
(수정/삭제할 데이터가 없다)
updateMany -- 수정
여러 데이터를 한꺼번에 수정
| 성공 | 대상 데이터가 없을 경우 | 실행중 에러 발생 |
| { count: number } | { count: 0 } (성공 취급) | Error 던짐 |
await db.test.updateMany({
where: { status: "PENDING" },
data: { status: "EXPIRED" }
});
delete / deleteMany -- 삭제
데이터를 삭제
✓ 실제 서비스에서는 status를 'DELETED'로 바꾸는 Soft Delete를 더 추천
| 성공 | 대상 데이터가 없을 경우 | 실행중 에러 발생 | |
| delete | 삭제된 Object | Error 던짐 (P2025) | Error 던짐 |
| deleteMany | { count: number } | { count: 0 } (성공 취급) | Error 던짐 |
await db.test.delete({
where: { id: "clx123..." }
});
count / aggregate -- 집계 및 계산
데이터 개수나 합계, 평균을 구할 때 사용
- 성공 -- Number
- 실패 --, 조건에 맞는게 없다면 0을 리턴
| 성공 | 대상 데이터가 없을 경우 | 실행중 에러 발생 | |
| count | 0 (Number) | 0 (Number) | Error 던짐 |
| aggregate | 요청한 집계 결과를 담은 객체(Object) 반환 | null로 채워진 객체 | Error 던짐 |
const totalCount = await db.test.count({
where: { status: "COMPLETED" }
});
const sumPrice = await db.test.aggregate({
_sum: { price: true },
where: { storeId: "store_abc" }
});
연산자 요약
where 절 내에서 연산자를 제공
| 연산자 | 설명 | 예시 |
| gt / gte | 초과/이상 | { gte: 1000 } (1000원 이상) |
| lt / lte | 미만/이하 | { lt: 5000 } (5000원 미만) |
| contains | 포함(LINK) | { contains: '치킨' } (문자열 검색) |
| in | 포함리스트 | { in: ['PENDING', 'COMPLETED'] } |
| not | 제외 | { not: 'EXPIRED' } |
⚠️ 무료 티어 DB를 사용 중이라면
- findMany를 사용할 때 항상 take를 걸어 가져오는 데이터 양을 제한하고, select를 사용하여 불필요한 필드(특히 긴 메모나 관계 데이터)를 조회하지 않는 것이 중요
- 차트를 그리거나 대시보드를 만들 때, 백엔드(Prisma)에서 aggregate나 groupBy로 계산을 끝내서 결과값만 받는 것이 좋다
(수천 개의 데이터를 클라이언트로 가져와서 자바스크립트로 계산하면 브라우저도 느려지고 DB 호출 비용(데이터 전송량)도 많이 발생)
💬
프로젝트를 진행할때, Prisma를 사용하는데,
헷갈리는 리턴 타입 그리고 무료로 사용중이기때문에 주의해야할 점이 무엇인지를 정리해두면 좋겠다고 생각해서
최대한 간단하게 정리해봤습니다.
반응형
'STUDY' 카테고리의 다른 글
| Next.js(App Router) URL의 파라미터(id)를 가져오는 방식 (서버 컴포넌트와 클라이언트 컴포넌트) (0) | 2026.01.12 |
|---|---|
| SEO를 위한 시맨틱 마크업 (0) | 2026.01.10 |
| Zustand와 Next.js, 안전한 데이터 동기화(Hydration) (0) | 2026.01.04 |
| React Router DOM부터 App Router까지 (0) | 2026.01.03 |
| 상태 관리 라이브러리 -- Zustand (0) | 2026.01.02 |