Prisma๋Š” ํ˜„๋Œ€์ ์ธ TypeScript ๊ธฐ๋ฐ˜ ORM(Object-Relational Mapping) ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํˆด์ด์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ๊ฐ์ฒด์ง€ํ–ฅ ์ฝ”๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.
SQL ์ž‘์„ฑ ์—†์ด๋„ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ณ  ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํƒ€์ž… ์•ˆ์ „์„ฑ๊ณผ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

โ“ ํˆด๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฐจ์ด

๊ตฌ๋ถ„๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํˆด (Tool, CLI ๋„๊ตฌ)
๋ชฉ์ ์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ๊ธฐ๋Šฅ์„ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉ์™ธ๋ถ€์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ์ž๋™ํ™”
์˜ˆ์‹œ@prisma/client, lodash, axiosnpx prisma migrate, git, webpack
์‚ฌ์šฉ ์œ„์น˜์ฝ”๋“œ ์•ˆ (importํ•ด์„œ ์‚ฌ์šฉ)ํ„ฐ๋ฏธ๋„์ด๋‚˜ ๋ช…๋ น์–ด ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ
๊ธฐ๋ŠฅDB ์š”์ฒญ, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋“ฑ ๋Ÿฐํƒ€์ž„ ๋กœ์งDB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ์ฝ”๋“œ ์ƒ์„ฑ, ์ดˆ๊ธฐํ™” ์ž‘์—… ๋“ฑ

๐Ÿ’ก Extendsion ์„ค์น˜ ๊ถŒ์žฅ

  • ์„ค์น˜ ํ•˜์ง€ ์•Š์„ ์‹œ shema.prisma - code๋“ค์˜ ์ƒ‰์ด ํฐ์ƒ‰์œผ๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค.

โœ… Prisma์˜ ์ฃผ์š” ์žฅ์ 

ํ•ญ๋ชฉ์„ค๋ช…
ํƒ€์ž… ์•ˆ์ •์„ฑDB ๋ชจ๋ธ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž๋™ ํƒ€์ž… ์ƒ์„ฑ๋˜์–ด ์ฝ”๋“œ ์ž‘์„ฑ ์ค‘ ์˜ค๋ฅ˜ ์˜ˆ๋ฐฉ
๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ•๋ฉ”์„œ๋“œ ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ์ง๊ด€์ ์ธ ์ฟผ๋ฆฌ ์ž‘์„ฑ ๊ฐ€๋Šฅ
์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜Prisma CLI๋กœ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ โ†’ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ž๋™ ์ƒ์„ฑ
ํ”„๋ก ํŠธ์—”๋“œ ์นœํ™”์ Next.js ๋“ฑ TypeScript ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ์™€ ๊ถํ•ฉ์ด ๋งค์šฐ ์ข‹์Œ
๋น ๋ฅธ ์ƒ์‚ฐ์„ฑPrisma Studio๋ฅผ ํ†ตํ•ด GUI๋กœ ๋ฐ์ดํ„ฐ ํ™•์ธ ๋ฐ ์ˆ˜์ • ๊ฐ€๋Šฅ

โš ๏ธ Prisma์˜ ๋‹จ์ 

ํ•ญ๋ชฉ์„ค๋ช…
๋ณต์žกํ•œ ์ฟผ๋ฆฌ์— ํ•œ๊ณ„๋ณต์žกํ•œ join/subquery๋Š” native SQL๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ
๊ด€๊ณ„ ๋งคํ•‘ ํ‘œํ˜„์˜ ์ œ์•ฝ์ผ๋ถ€ ๊ณ ๊ธ‰ ๊ด€๊ณ„ ์„ค์ •์€ ํ‘œํ˜„์ด ๋‹ค์†Œ ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ์Œ
๋Ÿฐํƒ€์ž„ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๋‚ด๋ถ€ ์ถ”์ƒํ™”(abstraction) ๊ตฌ์กฐ๋กœ ์„ฑ๋Šฅ ์ด์Šˆ ๋ฐœ์ƒ ๊ฐ€๋Šฅ (๊ทน๋‹จ์  ๊ฒฝ์šฐ)

๐Ÿ”ง ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

1.์„ค์น˜


npm install prisma tsx --save-dev
npx prisma init
npm install @prisma/client

prisma init ์‹คํ–‰ ์‹œ prisma/schema.prisma ํŒŒ์ผ๊ณผ .env ํŒŒ์ผ์ด ์ƒ์„ฑ๋จ.

2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์„ค์ •

.env ํŒŒ์ผ์—์„œ DB ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"

โœ… DB ๋ฌธ์ž์—ด(DATABASE_URL ์ฐพ๋Š” ๋ฐฉ๋ฒ•) supabase ๊ธฐ์ค€

  1. https://supabase.com/ ์ ‘์†
  2. ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ
  3. project ์ƒ์„ฑ
  4. ์ƒ๋‹จ ์šฐ์ธก Connect ํด๋ฆญ
  5. ORMs ํด๋ฆญ
  6. ๋ณต์‚ฌํ›„ .env์— ๋ณต์‚ฌ
    (2025.06.10 ๊ธฐ์ค€ โŒconntetion string์œผ๋กœ ํ•˜๋ฉด ์—๋ŸฌโŒ)

3. ๋ชจ๋ธ ์ •์˜ (schema.prisma)

๋ชจ๋ธ ์ •์˜์˜ ์ž์„ธํ•œ ๋ฐฉ๋ฒ•์€ ์—ฌ๊ธฐ์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
  posts Post[]
}

model Post {
  id      Int    @id @default(autoincrement())
  title   String
  content String?
  author  User   @relation(fields: [authorId], references: [id])
  authorId Int
}

4. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ ์šฉ

npx prisma migrate dev --name init

DB์— ํ…Œ์ด๋ธ” ์ƒ์„ฑ๋จ
๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ์ž๋™ ์ƒ์„ฑ๋จ

5. Prisma Client ์‚ฌ์šฉ ์˜ˆ์‹œ

PrismaClient: Prisma๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ DB์ ‘๊ทผ ๋„๊ตฌ, SQL์—†์ด DB๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํ•ต์‹ฌ ๊ฐ์ฒด

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
// create: instert ์ฟผ๋ฆฌ ์—ญํ• , ํ˜„์žฌ post์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ๋ฉ”์„œ๋“œ
  const user = await prisma.user.create({
    data: {
      name: 'ํ™๊ธธ๋™',
      email: 'hong@example.com',
      posts: {
        create: {
          title: '์ฒซ ๋ฒˆ์งธ ๊ฒŒ์‹œ๋ฌผ',
        },
      },
    },
  });
// findMany: select ์ฟผ๋ฆฌ ์—ญํ• , ๋ฐ์ดํ„ฐ ์—ฌ๋Ÿฌ ๊ฐœ ์กฐํšŒ, ์กฐ๊ฑด์„ ๋„ฃ์œผ๋ฉด ํ•„ํ„ฐ๋ง๋„ ๊ฐ€๋Šฅ 
  const allUsers = await prisma.user.findMany({
  // include: join์˜ ์—ญํ• , ํ˜„์žฌ usser๋ฅผ ์ฐพ์„๋•Œ ์—ฐ๊ด€๋œ posts๋„ ํ•จ๊ป˜ ๊ฐ€์ ธ์™€์ค˜ ๋ผ๋Š” ์˜๋ฏธ
    include: {
      posts: true,
    },
  });

  console.log(allUsers);
}

// ์‹ค์ œ๋กœ ์‹คํ–‰
main();

๐Ÿ–ฅ๏ธ ์ฃผ์š” ํ„ฐ๋ฏธ๋„ ๋ช…๋ น์–ด

๋ช…๋ น์–ด์„ค๋ช…
npx prisma init์ดˆ๊ธฐ ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ
npx prisma generatePrisma Client ์žฌ์ƒ์„ฑ (๋ชจ๋ธ ๋ณ€๊ฒฝ ์‹œ ํ•„์š”)
npx prisma migrate dev (--name [์„ค๋ช…])๊ฐœ๋ฐœ์šฉ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ˆ˜ํ–‰- prisma ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ-> DB์— ๋ฐ˜์˜
npx prisma studio์›น ๊ธฐ๋ฐ˜ GUI(DB ๋ธŒ๋ผ์šฐ์ €) ์‹คํ–‰
npx prisma formatschema.prisma ํŒŒ์ผ ํฌ๋งท ์ •๋ฆฌ(ํฌ๋งทํŒ…): ๊ฐ€๋…์„ฑ ์ฆ๊ฐ€
npx prisma db pull๊ธฐ์กด DB์—์„œ ์Šคํ‚ค๋งˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ- DB ๋ณ€๊ฒฝ-> Prisma ์Šคํ‚ค๋งˆ ๋ฐ˜์˜ (๋ฐ˜๋Œ€๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ)
npx prisma migrate reset๐Ÿšจ ๊ธฐ์กด DB ์ดˆ๊ธฐํ™”(Shema ํฌํ•จ ๋ฐ์ดํ„ฐ ์œ ์‹ค, ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉ)

๐Ÿ—‚ SQL vs Prisma ๋ฌธ๋ฒ• ๋น„๊ต

์ž‘์—…SQLPrisma
โœ… ๋ฐ์ดํ„ฐ ์ƒ์„ฑ (INSERT)INSERT INTO users (name, email) VALUES ('ํ™๊ธธ๋™', 'hong@example.com');await prisma.user.create({ data: { name: 'ํ™๊ธธ๋™', email: 'hong@example.com' } });
๐Ÿ” ์ „์ฒด ์กฐํšŒ (SELECT all)SELECT * FROM users;await prisma.user.findMany();
๐Ÿ” ์กฐ๊ฑด ์กฐํšŒ (SELECT with WHERE)SELECT * FROM users WHERE email = 'hong@example.com';await prisma.user.findMany({ where: { email: 'hong@example.com' } });
โœ๏ธ ์ˆ˜์ • (UPDATE)UPDATE users SET name = '๊น€์ฒ ์ˆ˜' WHERE id = 1;await prisma.user.update({ where: { id: 1 }, data: { name: '๊น€์ฒ ์ˆ˜' } });
โŒ ์‚ญ์ œ (DELETE)DELETE FROM users WHERE id = 1;await prisma.user.delete({ where: { id: 1 } });
๐Ÿ”— ์กฐ์ธ ํฌํ•จ ์กฐํšŒ (JOIN)SELECT * FROM users u JOIN posts p ON u.id = p.user_id;await prisma.user.findMany({ include: { posts: true } });
๐Ÿงต ๊ด€๊ณ„ ํฌํ•จ ์ƒ์„ฑ (user์™€ post ํ•จ๊ป˜ ์ƒ์„ฑ)INSERT INTO users ...; INSERT INTO posts (user_id, title) VALUES (...);await prisma.user.create({ data: { name: '', posts: { create: { title: '' } } } });
๐Ÿ”„ Upsert (์žˆ์œผ๋ฉด ์ˆ˜์ •, ์—†์œผ๋ฉด ์ƒ์„ฑ)(SQL์€ ๋ณต์žกํ•œ ์กฐ๊ฑด๋ฌธ ํ•„์š”)await prisma.user.upsert({ where: { email }, update: { name }, create: { email, name } });

๐Ÿ“ฆ Prisma ์ฃผ์š” ๋ฉ”์„œ๋“œ ์ •๋ฆฌ
๐Ÿ”น Create (๋ฐ์ดํ„ฐ ์ƒ์„ฑ)

๋ฉ”์„œ๋“œ์„ค๋ช…
create()๋‹จ์ผ ๋ ˆ์ฝ”๋“œ ์ƒ์„ฑ
createMany()์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ ํ•œ ๋ฒˆ์— ์ƒ์„ฑ

๐Ÿ” Read (๋ฐ์ดํ„ฐ ์กฐํšŒ)

๋ฉ”์„œ๋“œ์„ค๋ช…
findUnique()๊ณ ์œ  ์กฐ๊ฑด์œผ๋กœ ๋‹จ์ผ ๋ ˆ์ฝ”๋“œ ์กฐํšŒ (e.g. id)
findFirst()์กฐ๊ฑด์— ๋งž๋Š” ์ฒซ ๋ฒˆ์งธ ๋ ˆ์ฝ”๋“œ ์กฐํšŒ
findMany()์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ ์กฐํšŒ
count()์กฐ๊ฑด์— ๋งž๋Š” ๋ ˆ์ฝ”๋“œ ์ˆ˜ ๋ฐ˜ํ™˜
aggregate()sum, avg, max, min, count ๋“ฑ ์ง‘๊ณ„ ํ•จ์ˆ˜
groupBy()ํ•„๋“œ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ํ†ต๊ณ„ ๊ณ„์‚ฐ

โœ๏ธ Update (๋ฐ์ดํ„ฐ ์ˆ˜์ •)

๋ฉ”์„œ๋“œ์„ค๋ช…
update()๋‹จ์ผ ๋ ˆ์ฝ”๋“œ ์ˆ˜์ •
updateMany()์กฐ๊ฑด์— ๋งž๋Š” ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ ์ˆ˜์ •

๐Ÿ” Upsert (์กฐ๊ฑด๋ถ€ ์‚ฝ์ž… or ์ˆ˜์ •)

๋ฉ”์„œ๋“œ์„ค๋ช…
upsert()์กด์žฌํ•˜๋ฉด update, ์—†์œผ๋ฉด create ์ˆ˜ํ–‰

๐Ÿ’ก ๊ธฐํƒ€ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ

๋ฉ”์„œ๋“œ์„ค๋ช…
include๊ด€๊ณ„ ํ…Œ์ด๋ธ” ๊ฐ™์ด ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ
selectํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ์„ ํƒํ•ด์„œ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ
orderBy์ •๋ ฌ
where์กฐ๊ฑด ์ง€์ •
distinct์ค‘๋ณต ์ œ๊ฑฐ
profile
๋‹จ์ˆœ ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹Œ, ์ดํ•ดํ•˜๊ณ  ๋งŒ๋“œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ก.

0๊ฐœ์˜ ๋Œ“๊ธ€