네! 새로 변경된 회원 관리 테이블 관계도를 정리해드리겠습니다.
┌─────────────────────────────────────────────────────────────────┐
│ members │
│─────────────────────────────────────────────────────────────────│
│ PK id BIGINT │
│ UK member_uuid VARCHAR(36) │
│ UK email VARCHAR(100) │
│ UK user_id VARCHAR(50) │
│ UK phone_number VARCHAR(20) ← 중복 방지 키 │
│ password VARCHAR(255) │
│ name VARCHAR(50) │
│ member_type ENUM (DIRECT, SOCIAL_KAKAO, ...) │
│ status ENUM (ACTIVE, SUSPENDED, WITHDRAWN) │
│ @Deprecated company_name, business_number, ... │
│ created_at DATETIME │
│ updated_at DATETIME │
└─────────────────────────────────────────────────────────────────┘
│
│ 1
│
┌───────────┴───────────┐
│ │
│ N │ 1
▼ ▼
┌─────────────────────┐ ┌──────────────────────────────┐
│ member_roles │ │ corporate_info │
│─────────────────────│ │──────────────────────────────│
│ PK member_id │ │ PK id BIGINT │
│ PK role │ │ UK member_id BIGINT │
│ (복합키) │ │ company_name │
│ │ │ business_number │
│ role VALUES: │ │ business_address │
│ - INDIVIDUAL_USER │ │ business_phone │
│ - CORPORATE_USER │ │ approval_status ENUM │
│ │ │ applied_at │
│ │ │ approved_at │
│ │ │ approved_by │
│ │ │ approval_note │
└─────────────────────┘ └──────────────────────────────┘
approval_status VALUES:
- PENDING (승인 대기)
- APPROVED (승인 완료)
- REJECTED (승인 거부)
- SUSPENDED (자격 정지)
@ElementCollection (JPA)member_id + role이 복합 PK@OneToOne (JPA)member_id가 FK이자 UK (unique)business_number도 unique (사업자등록번호 중복 방지)members:
┌────┬──────────────────────────────────────┬─────────────────────┬──────────────┐
│ id │ member_uuid │ email │ phone_number │
├────┼──────────────────────────────────────┼─────────────────────┼──────────────┤
│ 17 │ 0abd52f3-68f6-4768-abbb-e4f90ff8cba4 │ fresh_individual@.. │ 010-9000-0001│
└────┴──────────────────────────────────────┴─────────────────────┴──────────────┘
member_roles:
┌───────────┬─────────────────┐
│ member_id │ role │
├───────────┼─────────────────┤
│ 17 │ INDIVIDUAL_USER │
└───────────┴─────────────────┘
corporate_info:
(없음)
members:
┌────┬──────────────────────────────────────┬─────────────────────┬──────────────┐
│ id │ member_uuid │ email │ phone_number │
├────┼──────────────────────────────────────┼─────────────────────┼──────────────┤
│ 18 │ 957f5c3d-91c8-4c1a-8ea8-eb7762654cf9 │ fresh_corporate@.. │ 010-9000-0002│
└────┴──────────────────────────────────────┴─────────────────────┴──────────────┘
member_roles:
┌───────────┬─────────────────┐
│ member_id │ role │
├───────────┼─────────────────┤
│ 18 │ INDIVIDUAL_USER │ ← 일반 기능도 사용 가능
│ 18 │ CORPORATE_USER │ ← 법인 전용 기능 사용
└───────────┴─────────────────┘
corporate_info:
┌────┬───────────┬──────────────────┬─────────────────┬─────────────────┐
│ id │ member_id │ company_name │ business_number │ approval_status │
├────┼───────────┼──────────────────┼─────────────────┼─────────────────┤
│ 2 │ 18 │ 테스트주식회사 │ 999-88-77777 │ PENDING │
└────┴───────────┴──────────────────┴─────────────────┴─────────────────┘
members:
┌────┬──────────────────────────────────────┬─────────────────────┬──────────────┐
│ id │ member_uuid │ email │ phone_number │
├────┼──────────────────────────────────────┼─────────────────────┼──────────────┤
│ 17 │ 0abd52f3-68f6-4768-abbb-e4f90ff8cba4 │ fresh_individual@.. │ 010-9000-0001│
└────┴──────────────────────────────────────┴─────────────────────┴──────────────┘
↑ 같은 행 (중복 생성 X)
member_roles:
┌───────────┬─────────────────┐
│ member_id │ role │
├───────────┼─────────────────┤
│ 17 │ INDIVIDUAL_USER │ ← 기존 역할
│ 17 │ CORPORATE_USER │ ← 추가된 역할
└───────────┴─────────────────┘
corporate_info:
┌────┬───────────┬──────────────────┬─────────────────┬─────────────────┐
│ id │ member_id │ company_name │ business_number │ approval_status │
├────┼───────────┼──────────────────┼─────────────────┼─────────────────┤
│ 3 │ 17 │ 추가법인주식회사 │ 111-22-33333 │ REJECTED │
└────┴───────────┴──────────────────┴─────────────────┴─────────────────┘
회원가입 시:
1. phone_number로 기존 회원 검색
2. 존재하면 → 역할만 추가 (member_roles INSERT)
3. 없으면 → 새 회원 생성 + 역할 추가
4. CORPORATE 타입이면 → corporate_info 생성 (PENDING 상태)
{
"userInfo": {
"roles": ["INDIVIDUAL_USER", "CORPORATE_USER"],
"corporateInfo": {
"approvalStatus": "PENDING",
"approvalMessage": "법인 회원 승인 대기 중입니다..."
},
"hasIndividualAccess": true,
"hasCorporateAccess": true
}
}
SELECT
m.id,
m.name,
m.email,
GROUP_CONCAT(mr.role) as roles
FROM members m
LEFT JOIN member_roles mr ON m.id = mr.member_id
WHERE m.phone_number = '010-9000-0001'
GROUP BY m.id;
SELECT
m.*,
ci.company_name,
ci.approval_status
FROM members m
JOIN member_roles mr ON m.id = mr.member_id AND mr.role = 'CORPORATE_USER'
LEFT JOIN corporate_info ci ON m.id = ci.member_id
WHERE ci.approval_status = 'PENDING';
이 구조로 1인 다역할 시스템이 완벽하게 구현되었습니다! 🎉