- Account = 계정
- Character = 캐릭터
- InventoryItem = 인벤토리 아이템
- Mail = 게임 내 우편
- MailAttachment = 우편 첨부 아이템
- TradeLog = 거래 기록
* FK : 이 데이터가 진짜 주인이 있는지 확인하는 장치
예를 들어,
- InventoryItem.character_id
- Mail.sender_character_id
- TradeLog.buyer_character_id
이런 컬럼이 있다고 해보자.
존재하지 않는 캐릭터에게 아이템이 들어가 있으면 안 되는데 없는 캐릭터가 우편을 보낸 걸로 저장하면 안 된다.
이미 삭제된 캐릭터가 인벤토리에 아이템을 들고 있으면 이상하고, 존재하지 않는 유저가 거래를 했다고 나오면 버그 처럼 보임
따라서, "FK는 데이터를 반드시 실제 존재하는 부모 데이터를 참조해야 한다" 라는 안전장치 이다.
즉, FK = 운영자가 엉뚱한 NPC한테 유저 인벤토리를 붙여버리지 못하게 막는 시스템 규칙
* CASCADE : 주인 지우면 딸린 것도 자동 삭제
이제 캐릭터 삭제를 생각해보자.
Character 1 : N InventoryItem
Character 1 : N Mail
Character 1 : N TradeLog
여기서 ON DELETE CASCADE를 걸면,
캐릭터 1명 삭제
→ 그 캐릭터 인벤토리 아이템 삭제
→ 우편 삭제
→ 친구 목록 삭제
→ 일부 로그 삭제
→ 관련 데이터가 줄줄이 자동 삭제
처음엔 되게 편리하게 캐릭터 지웠으니 관련 데이터도 같이 지워지면 깔끔하다고 생각할 수 있다.
하지만 라이브 운영 에서는 이 점을 조심해야 함.
게임 운영자는 '삭제' 보다 '보관'을 더 많이 한다는 것.
예를 들어 어떤 유저가 고객센터에 문의했다는 상황을 생각해보자.
“제가 분명히 전설 아이템을 갖고 있었는데 사라졌어요.”
이때 운영팀은 봐야 해:
- 그 유저 캐릭터 정보
- 인벤토리 이력
- 거래 기록
- 우편 첨부 이력
- 회수/지급 이력
근데 계정 삭제나 캐릭터 삭제에 CASCADE가 걸려 있으면 관련 로그나 연결 데이터가 같이 날아갔을 수 있어.
그러면 운영팀은 확인을 못 하는 상황이 생기는데,
게임에서 이건 치명적이다.
- 복구 근거가 없어짐
- 악성 유저 추적 어려움
- 현금성 재화/아이템 분쟁 대응 불가
- GM이 실수 한 번 하면 연쇄 삭제 사고
그래서 실무에서는 보통 이렇게 생각한다. “없애기보다 비활성화하자.”
- 계정 삭제 대신 status = withdrawn
- 캐릭터 삭제 대신 deleted_at만 저장
- 화면에서는 안 보이게 하고, 데이터는 남김
이걸 soft delete라고 하는데, 게임으로 치면 캐릭터를 쓰레기통에 버리는 게 아니라, GM 창고 뒤편 보관실에 잠깐 넣어두는 느낌이야.
UI/UX 피드백
포인트 부족 Alert보다는 충전 페이지 이동이 더 자연스럽다
이건 게임에서 완전 흔한 흐름인데, 예를 들어 캐시 아이템 사려는데 캐시가 부족하다
안 좋은 UX:
- “캐시가 부족합니다” 알림창만 뜸
- 유저가 직접 상점 나가서 충전 메뉴 다시 찾아야 함
좋은 UX:
- “캐시가 부족합니다”
- 바로 충전소/캐시샵으로 이동 버튼 제공
즉, 막고 끝내지 말고 다음 행동으로 연결해줘야 한다
- 포인트 부족 알림만 띄우는 것보다
- “충전하러 가기”로 이어주는 게 자연스럽다
이건 게임에서
“마나 부족입니다”만 띄우는 것보다 포션 상점으로 보내주는 게 낫다 는 느낌이로 생각하는게 좋을 거 같다.
핵심 정리!
FK:
게임에서 아이템의 주인이 실제 존재하는 캐릭터인지 확인하는 장치
CASCADE:
캐릭터 삭제하면 인벤토리, 우편, 첨부, 친구목록까지 자동 삭제되는 옵션
왜 실무에서 조심?:
라이브 운영에서는 복구, 분쟁 대응, 로그 조사가 중요해서
자동 연쇄 삭제가 위험함
soft delete:
캐릭터를 진짜 지우는 게 아니라
접속만 막고 DB에는 남겨두는 방식
파일 테이블 누락:
우편 시스템은 있는데
첨부 아이템 창고 테이블이 빠진 상태