✒️ 상품과 키워드 테이블 분리

박상은·2022년 4월 16일
0

🛒 blemarket 🛒

목록 보기
3/7

키워드는 연관 상품을 검색할 때 사용합니다. ( 키워드는 공백 기준으로 분리해서 입력받습니다. )

🤔 기존 방식과 현재 방식 비교

기존 방식은 product테이블에 키워드를 문자열을 그대로 넣는 방식을 사용했습니다.

이후에 검색어 자동완성 기능을 만들려고 할 때 곰곰이 생각해 보니 키워드가 중복될 때의 데이터가 반복되는 문제가 있으며, 가져올 때도 더 편하고 쉽게 구분해서 가져오도록 하려다 보니까 키워드 테이블을 따로 분리해서 N : M관계로 생성하는 것이 더 좋다고 생각해서 분리했습니다.

  • 기존 스키마 정의 ( prisma )
model Product {
  id          Int      @id @default(autoincrement())
  name        String   @db.VarChar(30)
  price       Int
  description String   @db.MediumText
  image       String?
  keywords	  String   @db.VarChar(40)
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  records  Record[]
  answers  Answer[]

  user   User @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId Int

  @@index([userId])
}
  • 현재 스키마 정의 ( prisma )
model Product {
  id          Int      @id @default(autoincrement())
  name        String   @db.VarChar(30)
  price       Int
  description String   @db.MediumText
  image       String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  records  Record[]
  answers  Answer[]
  keywords Keyword[]

  user   User @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId Int

  @@index([userId])
}

model Keyword {
  id        Int      @id @default(autoincrement())
  keyword   String   @unique @db.VarChar(20)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  products Product[]
}

😀 사용 코드 변경 예시

  • 기존 게시글 생성 코드
// async 함수 내부에 있다고 가정
const createdProduct = await prisma.product.create({
  data: {
    name,
    price: +price,
    description,
    image: photo ? photo : null,
    keywords,
    user: {
      connect: {
        id: user?.id,
      },
    },
  },
});
  • 현재 게시글 생성 코드
// async 함수 내부에 있다고 가정
const createdProduct = await prisma.product.create({
  data: {
    name,
    price: +price,
    description,
    image: photo ? photo : null,
    user: {
      connect: {
        id: user?.id,
      },
    },
  },
});

// 키워드 생성 or 찾고 상품과 연결
const keywordsPromise = (keywords as string).split(" ").map((keyword) =>
  prisma.keyword.upsert({
    create: {
      keyword,
      products: {
        connect: {
          id: createdProduct.id,
        },
      },
    },
    update: {
      products: {
        connect: {
          id: createdProduct.id,
        },
      },
    },
    where: {
      keyword,
    },
  })
);

await Promise.all(keywordsPromise);

🔎 마무리

나머지 상품 가져오기, 연관 상품 가져오기 등의 코드도 변경된 형태에 맞게 수정했습니다.

0개의 댓글