-
Notifications
You must be signed in to change notification settings - Fork 2
멀티 호스트 지원
wlgh1553 edited this page Dec 4, 2024
·
3 revisions
- 시작: 세션에서 호스트 권한을 멀티플하게 부여하는 기능을 추가하고자 시도.
- 문제 발생: 조인 테이블을 도입하려던 초기 설계가 복잡해지고, 실제 요구사항과 맞지 않는 구조를 만들 가능성이 생김.
- 최종 설계: 호스트를 슈퍼호스트(Super Host)와 서브호스트(Sub Host)로 구분하여, createUserId 필드를 통해 슈퍼호스트를 관리하고, isHost 필드를 통해 서브호스트 권한을 부여.
-
멀티 호스트 지원:
- 세션에서 여러 사용자가 호스트 권한을 가지도록 설계.
- 슈퍼호스트와 서브호스트의 역할과 권한을 명확히 구분.
- 세션 내 권한 변경과 부여 과정이 효율적이어야 함.
1. 조인 테이블 방식
설계 시도:
-
기존 테이블
model User { userId Int @id @default(autoincrement()) @map("user_id") email String @unique password String nickname String @unique createdAt DateTime @default(now()) @map("created_at") sessions Session[] @relation("UserSessions") userSessionTokens UserSessionToken[] @relation("UserTokens") } model Session { sessionId String @id @default(uuid()) @map("session_id") title String expiredAt DateTime @map("expired_at") createdAt DateTime @default(now()) @map("created_at") createUserId Int @map("create_user_id") user User @relation("UserSessions", fields: [createUserId], references: [userId]) userSessionTokens UserSessionToken[] @relation("SessionTokens") questions Question[] @relation("SessionQuestions") replies Reply[] @relation("SessionReplies") chattings Chatting[] @relation("SessionChattings") } model UserSessionToken { token String @id @default(uuid()) userId Int? @map("user_id") sessionId String @map("session_id") user User? @relation("UserTokens", fields: [userId], references: [userId]) session Session @relation("SessionTokens", fields: [sessionId], references: [sessionId]) questions Question[] @relation("TokenQuestions") questionLikes QuestionLike[] @relation("TokenQuestionLikes") replies Reply[] @relation("TokenReplies") replyLikes ReplyLike[] @relation("TokenReplyLikes") chattings Chatting[] @relation("TokenChattings") }
-
SessionHosts 조인 테이블 추가.
model SessionHosts {
sessionId String
userId Int
role String // "SUPER_HOST" 또는 "SUB_HOST" 지정
session Session @relation(fields: [sessionId], references: [sessionId])
user User @relation(fields: [userId], references: [userId])
@@id([sessionId, userId])
}-
조인 테이블 설계:
- Session과 User 간 다대다(M:N) 관계를 조인 테이블로 관리하려 함.
- 조인 테이블 설계로 인해 권한 계층 구조를 구현하는데 복잡성이 증가.
- 토큰기반 식별이기 때문에 토큰조회 → userId → sessionId, userId를 가지고 SessionHosts 테이블 조회라는 복잡한 과정이 생김.
- 실제 구현에서 슈퍼호스트는 단일 사용자로 제한되는데, 조인 테이블로 관리하는 것은 불필요한 복잡성 추가.
- 쿼리 작성 시 성능 문제 발생 가능.
-
권한 계층 문제:
- 조인 테이블만으로는 권한 계층과 역할에 대한 명확한 관리가 어려움.
설계 변경: 단순화된 권한 필드 사용
- Session 모델의 createUserId 필드를 사용하여 슈퍼호스트 관리.
- UserSessionToken 모델의 isHost 필드를 통해 서브호스트 관리. → 서브호스트의 권한만 있다면 충분한 일을 굳이 SUPER_HOST || SUB_HOST 연산을 이용하지 않아도 될 수 있게 됨.
최종 모델:
- 슈퍼호스트: Session.createUserId 필드를 사용하여 단일 관리.
- 서브호스트: UserSessionToken.isHost 필드를 사용하여 권한 관리.
model UserSessionToken {
token String @id @default(uuid())
userId Int? @map("user_id")
sessionId String @map("session_id")
isHost Boolean @default(false) @map("is_host")
user User? @relation("UserTokens", fields: [userId], references: [userId])
session Session @relation("SessionTokens", fields: [sessionId], references: [sessionId])
questions Question[] @relation("TokenQuestions")
questionLikes QuestionLike[] @relation("TokenQuestionLikes")
replies Reply[] @relation("TokenReplies")
replyLikes ReplyLike[] @relation("TokenReplyLikes")
chattings Chatting[] @relation("TokenChattings")
}| 특징 | 슈퍼 호스트(세션 생성자) | 서브 호스트 | 기명 참가자 | 익명 참가자 |
|---|---|---|---|---|
| 로그인 필요 여부 | ⭕ | ⭕ | ⭕ | ❌ |
| 세션 종료 권한 | ⭕ | ❌ | ❌ | ❌ |
| 타인에게 호스트 권한 부여/해제 권한 | ⭕ | ❌ | ❌ | ❌ |
| 타인의 질문 삭제 권한 | ⭕ | ⭕ | ❌ | ❌ |
| 타인의 답변 삭제 권한 | ⭕ | ⭕ | ❌ | ❌ |
| 답변에 ✔️ 뱃지 부여 및 상단으로 정렬 | ⭕ | ⭕ | ❌ | ❌ |
| 답변 고정 / 답변 완료 선택 권한 | ⭕ | ⭕ | ❌ | ❌ |
| 답변에 닉네임 명시 | ⭕ | ⭕ | ⭕ | ❌ |
1. 구조적 단순화
- 조인 테이블 없이 권한을 단일 필드로 관리.
- 데이터베이스 구조 단순화로 유지보수 용이.
2. 역할 명확화
- 슈퍼호스트는 Session.createUserId로 관리.
- 서브호스트는 UserSessionToken.isHost로 관리.
- 권한 계층 및 역할 구분 명확.
3. 성능 최적화
- 불필요한 조인 쿼리 제거로 데이터 접근 속도 향상.
- 단일 테이블 조회로 권한 부여/해제 효율성 증가.
4. 권한 관리 로직 간소화
- 슈퍼호스트는 세션 생성 시 자동 설정.
- 서브호스트는 update 메서드로 권한 부여/해제.