2023. 9. 6. 01:39ใ3. Node.js
๋๋ง์ ๊ฒ์ํ ์ฌ์ดํธ ์ค๊ณ
https://drawsql.app/teams/no-55/diagrams/prisma-community-hub
Prisma-Community-Hub | DrawSQL
Database schema diagram for Prisma-Community-Hub.
drawsql.app
์์คํ ์ ๊ตฌ์ฑ์ด ๋ฌด์์ด๊ณ ์ด๋ ํ ๊ด๊ณ๊ฐ ์๋์ง ํ์ธ์ด ๊ฐ๋ฅํ๋๋ก ๊ตฌ์ํ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ ERD
๋๋ง์ ๊ฒ์ํ ์ฌ์ดํธ ์ค๊ณ
[ ํ ์ด๋ธ ๊ด๊ณ ๋ฐ ์๊ตฌ์ฌํญ ]
์ฌ์ฉ์(Users)๋ 1๊ฐ์ ์ฌ์ฉ์ ์ ๋ณด(UserInfo)๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Users ํ ์ด๋ธ๊ณผ UserInfo ํ ์ด๋ธ์ 1:1 ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ฌ์ฉ์(Users)๋ ์ฌ๋ฌ๊ฐ์ ๊ฒ์๊ธ(Posts)์ ๋ฑ๋กํ ์ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Users ํ ์ด๋ธ๊ณผ Posts ํ ์ด๋ธ์ 1:N ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ฌ์ฉ์(Users)๋ ์ฌ๋ฌ๊ฐ์ ๋๊ธ(Comments)์ ์์ฑํ ์ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Users ํ ์ด๋ธ๊ณผ Comments ํ ์ด๋ธ์ 1:N ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
ํ๋์ ๊ฒ์๊ธ(Posts**)์ ์ฌ๋ฌ๊ฐ์ ๋๊ธ(Comments)**์ด ์์ฑ๋ ์ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Posts ํ ์ด๋ธ๊ณผ Comments ํ ์ด๋ธ์ 1:N ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
[ ์ฌ์ฉ์(User) ์๊ตฌ์ฌํญ ํ ์ด๋ธ ]
1. ์ฌ์ฉ์(Users) ํ ์ด๋ธ
// ์ฌ์ฉ์(Users) ํ
์ด๋ธ
// userId (PK) INTEGER NOT NULL AUTO_INCREMENT
// email STRING NOT NULL
// password STRING NOT NULL
// createdAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
// updatedAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
2. ๊ฒ์๊ธ(Posts) ํ ์ด๋ธ
// [์๊ตฌ์ฌํญ] ์ฌ์ฉ์(Users) ํ
์ด๋ธ
// postId (PK) INTEGER NOT NULL AUTO_INCREMENT
// title STRING NOT NULL
// content TEXT NOT NULL
// createdAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
// updatedAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
3. ์ฌ์ฉ์ ์ ๋ณด(UsersInfos) ํ ์ด๋ธ
// [์๊ตฌ์ฌํญ] ์ฌ์ฉ์(Users) ํ
์ด๋ธ
// userInfoId (PK) INTEGER NOT NULL AUTO_INCREMENT
// name STRING NOT NULL
// age INTEGER NULL
// gender STRING NOT NULL
// profileImage STRING NULL
// createdAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
// updatedAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
4. ๋๊ธ(Comments) ํ ์ด๋ธ
// [์๊ตฌ์ฌํญ] ๋๊ธ(Comments) ํ
์ด๋ธ
// commentId (PK) INTEGER NOT NULL AUTO_INCREMENT
// content STRING NOT NULL
// createdAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
// updatedAt DATETIME NOT NULL ํ์ฌ ์๊ฐ
[ ์๊ตฌ์ฌํญ์ ๋ฐ๋ฅธ, schema.prisma ๋ชจ๋ธ ]
// prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Users {
userId Int @id @default(autoincrement()) @map("userId")
email String @unique @map("email")
password String @map("password")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
@@map("Users")
}
model Posts {
postId Int @id @default(autoincrement()) @map("postId")
title String @map("title")
content String @map("content") @db.Text
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
@@map("Posts")
}
model UserInfos {
userInfoId Int @id @default(autoincrement()) @map("userInfoId")
name String @map("name")
age Int? @map("age")
gender String @map("gender")
profileImage String? @map("profileImage")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
@@map("UserInfos")
}
model Comments {
commentId Int @id @default(autoincrement()) @map("commentId")
content String @map("content")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
@@map("Comments")
}
[Prisma 1:1 ๊ด๊ณ]
์ฌ์ฉ์(Users) ๋ชจ๋ธ์ ์ฌ์ฉ์ ์ ๋ณด(UserInfos) ๋ชจ๋ธ๊ณผ 1:1 ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
1:1 ๊ด๊ณ๋ ํ ์ฌ์ฉ์๊ฐ ํ๋์ ์ฌ์ฉ์ ์ ๋ณด๋ง ๊ฐ์ง ์ ์๊ณ , ํ ์ฌ์ฉ์ ์ ๋ณด๋ ํ ์ฌ์ฉ์์๊ฒ๋ง ์ํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
1:1๊ด๊ณ๋ฅผ ์ค์ ํ ๋๋ ์๋์ ๋ด์ฉ์ ํฌํจํด์ผ ํ๋ค.
๊ด๊ณ๋ฅผ ์ค์ ํ๋ ค๋ ๋ชจ๋ธ(UserInfos)์์ ์ด๋ค ๋ชจ๋ธ๊ณผ ๊ด๊ณ๋ฅผ ๋งบ์์ง(Users) ์ค์ ํด์ผํฉ๋๋ค.
๊ด๊ณ๋ฅผ ๋งบ๊ฒ๋๋ ๋ชจ๋ธ(Users)์์ ์ด๋ค ๋ชจ๋ธ์ด ๊ด๊ณ๋ฅผ ๋งบ๋์ง(UserInfos) ์ค์ ํด์ผํฉ๋๋ค.
๊ด๊ณ๋ฅผ ๋งบ๊ฒ๋๋ ๋ชจ๋ธ(Users)์์, ํ์ ์ ์ง์ ํ ๋, Optional Parameter(?)๋ฅผ ์ง์ ํด์ค์ผํฉ๋๋ค.
// schema.prisma
model Users {
userId Int @id @default(autoincrement()) @map("userId")
email String @unique @map("email")
password String @map("password")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
UserInfos UserInfos? // ์ฌ์ฉ์(Users) ํ
์ด๋ธ๊ณผ ์ฌ์ฉ์ ์ ๋ณด(UserInfos) ํ
์ด๋ธ์ด 1:1 ๊ด๊ณ๋ฅผ ๋งบ์ต๋๋ค.
// userinfos์ด๊ธด ํ์ง๋ง, ํด๋น ๋ฐ์ดํฐ๊ฐ ์กด์ฌ ํ์ง ์์์๋ ์๋ค ๋ผ๋๊ฒ์ ๋ํ๋.
// ์ฌ์ฉ์์ ์ฌ์ฉ์์ ๋ณด๊ฐ ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ค๋๊ฒ์ ๋ํ๋
// model Users๋ ์ฐ๊ด๊ด๊ณ์ ์์ ์ปฌ๋ผ์ผ๋ฟ, ์ปฌ๋ผ์ ์๊ธฐ์ง์์!!!!!!
@@map("Users")
}
model UserInfos {
userInfoId Int @id @default(autoincrement()) @map("userInfoId")
UserId Int @unique @map("UserId") // ์ฌ์ฉ์(Users) ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค
name String @map("name")
age Int? @map("age")
gender String @map("gender")
profileImage String? @map("profileImage")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
// Users ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
// model user/info user์ userid๊ด๊ณ์ค์
// ๋๋ ์ฌ์ฉ์์ ๋ณดํ
์ด๋ธ์์๋ UserId ์ปฌ๋ผ์ ์ ์ ์คํ
์ด๋ธ์์๋ ์ ์ ์์ด๋ ์ปฌ๋ผ์ ์ฐธ์กฐํ ๊ฑฐ๋ค.
onDelete: Cascade -> ์ฌ์ฉ์์ ๋ณด๊ฐ ์ญ์ ๋๋ฉด ์ ๋ณด๋ ์ญ์ ๋๋ค.
@@map("UserInfos")
}
์ฌ์ฉ์ ์ ๋ณด(UserInfos) ๋ชจ๋ธ์ ์ค์
Users : ์ผ๋ฐ์ ์ธ Int, String๊ณผ ๊ฐ์ ํ์ ์ด ์๋, ์ฐธ์กฐํ ๋ค๋ฅธ ๋ชจ๋ธ์ ์ง์
์ฌ์ฉ์(Users) ๋ชจ๋ธ์ ์ฐธ์กฐํ๋ฏ๋ก Users๋ก ์์ฑ๋์ด์๋ค.
fields : ์ฌ์ฉ์ ์ ๋ณด(UserInfos) ๋ชจ๋ธ์์ ์ฌ์ฉํ ์ธ๋ํค(Forien Key) ์ปฌ๋ผ์ ์ง์ .
์ฌ๊ธฐ์ , UserId ์ปฌ๋ผ์ผ๋ก ์ธ๋ํค๋ฅผ ์ง์ .
references : key: ์ฐธ์กฐํ๋ ๋ค๋ฅธ ๋ชจ๋ธ์ Column๋ฅผ ์ง์ .
์ฌ๊ธฐ์ , ์ฌ์ฉ์(Users) ๋ชจ๋ธ์ userId ์ปฌ๋ผ์ ์ฐธ์กฐ.
onDelete | onUpdate : ์ฐธ์กฐํ๋ ๋ชจ๋ธ์ด ์ญ์ or ์์ ๋ ๊ฒฝ์ฐ ์ด๋ค ํ์๋ฅผ ํ ์ง ์ค์ .
Cascade ์ต์ ์ ์ ํํ์ฌ ์ฌ์ฉ์๊ฐ ์ญ์ ๋ ๊ฒฝ์ฐ ๊ทธ์ ์ฐ๊ฒฐ๋ ์ฌ์ฉ์ ์ ๋ณด๋ ํจ๊ป ์ญ์ ๋๋๋ก ์ค์ .
[Prisma 1:N ์ฐ๊ด ๊ด๊ณ]
๊ฒ์๊ธ(Posts) ๋ชจ๋ธ์ ์ฌ์ฉ์(Users) ๋ชจ๋ธ๊ณผ N:1 ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ฌ๊ธฐ์, 1:N ๊ด๊ณ๋ ํ ์ฌ์ฉ์๋ ์ฌ๋ฌ๊ฐ์ ๊ฒ์๊ธ์ ์์ฑํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
1:N ๊ด๊ณ๋ฅผ ์ค์ ํ ๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ด์ฉ์ ํฌํจํด์ผ ํ๋ค.
๊ด๊ณ๋ฅผ ์ค์ ํ๋ ค๋ ๋ชจ๋ธ(Posts)์์ ์ด๋ค ๋ชจ๋ธ๊ณผ ๊ด๊ณ๋ฅผ ๋งบ์์ง(Users) ์ค์
๊ด๊ณ๋ฅผ ๋งบ๊ฒ๋๋ ๋ชจ๋ธ(Users)์์ ์ด๋ค ๋ชจ๋ธ์ด ๊ด๊ณ๋ฅผ ๋งบ๋์ง(Posts) ์ค์
๊ด๊ณ๋ฅผ ๋งบ๊ฒ๋๋ ๋ชจ๋ธ(Users)์์, ํ์ ์ ์ง์ ํ ๋, ๋ฐฐ์ด ์ฐ์ฐ์([])๋ฅผ ์์ฑ
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Users {
userId Int @id @default(autoincrement()) @map("userId")
email String @unique @map("email")
password String @map("password")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
UserInfos UserInfos? // ์ฌ์ฉ์(Users) ํ
์ด๋ธ๊ณผ ์ฌ์ฉ์ ์ ๋ณด(UserInfos) ํ
์ด๋ธ์ด 1:1 ๊ด๊ณ๋ฅผ ๋งบ์ต๋๋ค.
Posts Posts[] // ์ฌ์ฉ์(Users) ํ
์ด๋ธ๊ณผ ๊ฒ์๊ธ(Posts) ํ
์ด๋ธ์ด 1:N ๊ด๊ณ๋ฅผ ๋งบ์ต๋๋ค.
Comments Comments[] // ์ฌ์ฉ์(Users) ํ
์ด๋ธ๊ณผ ๋๊ธ(Comments) ํ
์ด๋ธ์ด 1:N ๊ด๊ณ๋ฅผ ๋งบ์ต๋๋ค.
@@map("Users")
}
model Posts {
postId Int @id @default(autoincrement()) @map("postId")
UserId Int @map("UserId") // ์ฌ์ฉ์(Users) ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค
title String @map("title")
content String @map("content") @db.Text
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
// Users ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
Comments Comments[] // ๊ฒ์๊ธ(Posts) ํ
์ด๋ธ๊ณผ ๋๊ธ(Comments) ํ
์ด๋ธ์ด 1:N ๊ด๊ณ๋ฅผ ๋งบ์ต๋๋ค.
@@map("Posts")
}
model UserInfos {
userInfoId Int @id @default(autoincrement()) @map("userInfoId")
UserId Int @unique @map("UserId") // ์ฌ์ฉ์(Users) ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค
name String @map("name")
age Int? @map("age")
gender String @map("gender")
profileImage String? @map("profileImage")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
// Users ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
@@map("UserInfos")
}
model Comments {
commentId Int @id @default(autoincrement()) @map("commentId")
PostId Int @map("PostId") // ๊ฒ์๊ธ(Posts) ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค
UserId Int @map("UserId") // ์ฌ์ฉ์(Users) ํ
์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค
content String @map("content")
createdAt DateTime @default(now()) @map("createdAt")
updatedAt DateTime @updatedAt @map("updatedAt")
// Posts ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
Post Posts @relation(fields: [PostId], references: [postId], onDelete: Cascade)
// Users ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
@@map("Comments")
}
* ๊ฒ์๊ธ ์ญ์ @relation
๊ฒ์๊ธ ๋ชจ๋ธ์ ๊ฒฝ์ฐ ์์ฑํ ์ฌ์ฉ์๊ฐ ํ์ ํํด(onDelete)ํ๊ฒ ๋ ๊ฒฝ์ฐ ์์ฑํ ๋ชจ๋ ๊ฒ์๊ธ์ด ์ญ์ ๋๋๋ก ๊ตฌํ๋์ด ์๋ค. ์ด๋ฐ ์ค์ ์ @relation ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ง์ ํ๋ค.
// Users ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
User๋ ๊ฒ์๊ธ(Posts)์ด ์ฐธ์กฐํ๋ ๋ค๋ฅธ ๋ชจ๋ธ์ ์ง์ ํ๊ณ , fields๋ ๊ฒ์๊ธ(Posts) ๋ชจ๋ธ์์ ์ฌ์ฉํ ์ธ๋ํค ์ปฌ๋ผ์ ์ง์ ํ๋ค.
references๋ ์ฐธ์กฐํ๋ ๋ค๋ฅธ ๋ชจ๋ธ์ ์ปฌ๋ผ์ ์ง์ ํ๊ณ , onDelete๋ ์ ์กฐํ๋ ๋ชจ๋ธ์ด ์ญ์ ๋ ๊ฒฝ์ฐ ์ด๋ค ํ์๋ฅผ ํ ์ง ์ค์ ํ๋ค.
onDelete์ ๊ฒฝ์ฐ, Cascade ์ต์ ์ผ๋ก ์ฌ์ฉ์๊ฐ ์ญ์ ๋ ๊ฒฝ์ฐ ์ฐ๊ด๋ ๊ฒ์๊ธ ๋ํ ์ญ์ ๋๋ค.

'3. Node.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [ Node.js ์๋ จ์ฃผ์ฐจ1 (1-0)] noSQL vs SQL (0) | 2023.09.11 |
|---|---|
| [ Node.js ์๋ จ์ฃผ์ฐจ1 (1-0)] ORM๊ณผ Prisma (0) | 2023.09.10 |
| [ Node.js ์๋ จ์ฃผ์ฐจ1 (1-9)] ์ฟ ํค์ ์ธ์ (0) | 2023.09.05 |
| [ Node.js ์๋ จ์ฃผ์ฐจ1 (1-3)] SQL (Structured Query Language) ์ดํด๋ณด๊ธฐ (0) | 2023.09.03 |
| [ Node.js ์๋ จ์ฃผ์ฐจ1 (1-1)] ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค (RDB) (3) | 2023.09.01 |