173 lines
5.4 KiB
Plaintext
173 lines
5.4 KiB
Plaintext
!theme mono
|
|
|
|
skinparam classAttributeIconSize 0
|
|
skinparam classFontSize 12
|
|
skinparam classAttributeFontSize 11
|
|
|
|
title HealthSync 역설계 - User Service 데이터 설계서
|
|
|
|
package "User Service Database Schema" as user_db #lightgreen {
|
|
|
|
entity "users" as user {
|
|
* member_serial_number : BIGINT <<PK>>
|
|
--
|
|
* google_id : VARCHAR(255) <<UK>>
|
|
* name : VARCHAR(100)
|
|
* birth_date : DATE
|
|
* occupation : VARCHAR(50) <<FK>>
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
* last_login_at : TIMESTAMP
|
|
--
|
|
+ 인덱스: idx_google_id
|
|
+ 인덱스: idx_occupation
|
|
+ 인덱스: idx_created_at
|
|
}
|
|
|
|
entity "occupation_types" as occupation_type {
|
|
* occupation_code : VARCHAR(20) <<PK>>
|
|
--
|
|
* occupation_name : VARCHAR(100)
|
|
* category : VARCHAR(50)
|
|
* is_active : BOOLEAN
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
--
|
|
+ 인덱스: idx_occupation_name
|
|
+ 인덱스: idx_category
|
|
}
|
|
|
|
note right of user
|
|
**사용자 테이블 특징**
|
|
• Google OAuth 기반 인증
|
|
• member_serial_number는
|
|
건강보험공단 데이터 연동 키
|
|
• occupation은 직업 코드 참조
|
|
• 소프트 삭제 미적용 (물리 삭제)
|
|
end note
|
|
|
|
note right of occupation_type
|
|
**직업 유형 테이블 특징**
|
|
• 표준 직업 분류 기반
|
|
• 카테고리별 그룹핑
|
|
• 활성/비활성 상태 관리
|
|
• 마스터 데이터 성격
|
|
end note
|
|
}
|
|
|
|
package "관계 정의" as relationships {
|
|
user ||--o{ occupation_type : occupation
|
|
|
|
note as n1
|
|
**외래키 관계**
|
|
users.occupation → occupation_types.occupation_code
|
|
|
|
**참조 무결성**
|
|
• CASCADE 업데이트
|
|
• RESTRICT 삭제 (직업 유형 삭제 시 제한)
|
|
|
|
**데이터 정합성**
|
|
• occupation 필드는 NULL 허용 (프로필 미완성 상태)
|
|
• birth_date는 NOT NULL (필수 정보)
|
|
• google_id는 UNIQUE 제약 (중복 가입 방지)
|
|
end note
|
|
}
|
|
|
|
package "데이터 타입 및 제약조건" as constraints {
|
|
note as n2
|
|
**users 테이블 제약조건**
|
|
• member_serial_number: AUTO_INCREMENT
|
|
• google_id: UNIQUE, NOT NULL
|
|
• name: NOT NULL, 최대 100자
|
|
• birth_date: NOT NULL, 1900-01-01 이후
|
|
• occupation: NULL 허용, 최대 50자
|
|
• created_at: DEFAULT CURRENT_TIMESTAMP
|
|
• updated_at: ON UPDATE CURRENT_TIMESTAMP
|
|
• last_login_at: NULL 허용
|
|
|
|
**occupation_types 테이블 제약조건**
|
|
• occupation_code: PRIMARY KEY, 최대 20자
|
|
• occupation_name: UNIQUE, NOT NULL, 최대 100자
|
|
• category: NOT NULL, 최대 50자
|
|
• is_active: DEFAULT TRUE
|
|
• created_at: DEFAULT CURRENT_TIMESTAMP
|
|
• updated_at: ON UPDATE CURRENT_TIMESTAMP
|
|
end note
|
|
}
|
|
|
|
package "초기 데이터" as initial_data {
|
|
note as n3
|
|
**occupation_types 초기 데이터 예시**
|
|
|
|
| occupation_code | occupation_name | category |
|
|
|----------------|----------------|----------|
|
|
| OFF001 | 사무직 | 사무관리 |
|
|
| MFG001 | 제조업 생산직 | 제조생산 |
|
|
| SVC001 | 서비스업 | 서비스 |
|
|
| EDU001 | 교육직 | 전문직 |
|
|
| MED001 | 의료진 | 전문직 |
|
|
| IT001 | IT개발자 | 전문직 |
|
|
| SAL001 | 영업직 | 영업마케팅 |
|
|
| DRV001 | 운전직 | 운송 |
|
|
| CON001 | 건설업 | 건설 |
|
|
| FRE001 | 프리랜서 | 기타 |
|
|
|
|
**카테고리 분류**
|
|
• 사무관리: 앉아서 일하는 직종
|
|
• 제조생산: 신체 활동이 많은 직종
|
|
• 서비스: 고객 응대 직종
|
|
• 전문직: 전문 지식 요구 직종
|
|
• 영업마케팅: 외부 활동 직종
|
|
• 운송: 이동이 많은 직종
|
|
• 건설: 육체 노동 직종
|
|
• 기타: 분류하기 어려운 직종
|
|
end note
|
|
}
|
|
|
|
package "성능 및 운영 고려사항" as performance {
|
|
note as n4
|
|
**인덱스 전략**
|
|
• users.google_id: 로그인 시 빠른 조회
|
|
• users.occupation: 직업별 통계 조회
|
|
• users.created_at: 가입 일자별 조회
|
|
• occupation_types.occupation_name: 직업명 검색
|
|
|
|
**파티셔닝**
|
|
• 현재 단계에서는 미적용
|
|
• 사용자 수 증가 시 created_at 기준 월별 파티셔닝 고려
|
|
|
|
**백업 및 복구**
|
|
• users: 매일 풀백업 (개인정보 보호)
|
|
• occupation_types: 주간 백업 (마스터 데이터)
|
|
|
|
**모니터링 지표**
|
|
• 신규 가입자 수 (일별/월별)
|
|
• 활성 사용자 수 (last_login_at 기준)
|
|
• 직업별 사용자 분포
|
|
• 평균 프로필 완성률
|
|
end note
|
|
}
|
|
|
|
package "데이터 보안" as security {
|
|
note as n5
|
|
**개인정보 보호**
|
|
• name: 암호화 저장 고려 (실명)
|
|
• birth_date: 날짜 정보 마스킹
|
|
• google_id: 해시 처리 또는 암호화
|
|
|
|
**접근 제어**
|
|
• 개인정보 조회 시 로그 기록
|
|
• 관리자 접근 시 승인 프로세스
|
|
• API 호출 시 사용자 본인 확인
|
|
|
|
**데이터 보존**
|
|
• 회원 탈퇴 시 개인정보 즉시 삭제
|
|
• 로그인 기록 90일 보존
|
|
• 감사 로그 1년 보존
|
|
|
|
**GDPR/개인정보보호법 준수**
|
|
• 데이터 처리 목적 명시
|
|
• 동의 철회 시 데이터 삭제
|
|
• 데이터 이동권 지원
|
|
end note
|
|
} |