SHOW CREATE TABLE 로 유저 테이블 컬럼을 쭉 봤다.
user_id, user_email, user_nick, user_level, user_exp,
user_coin, user_total_payment, user_state,
bigwin_coin, jackpot_coin, bigwin_multiple, jackpot_multiple,
max_coin, is_like, daily_date, last_visit, reg_date
스무 개 가까이 된다.
Table of contents
Open Table of contents
종류가 나뉘었다
읽다 보니 성격이 갈렸다.
신원 user_id, user_email, user_nick, reg_date
현재 상태 user_coin, user_level, user_exp, user_state, last_visit
누적 기록 bigwin_coin, jackpot_coin, bigwin_multiple, jackpot_multiple, max_coin
연동 상태 is_like, daily_date
신원은 거의 안 바뀌고 현재 상태는 게임 한 판마다 바뀐다. 앞의 둘은 유저 테이블에 있는 것이 자연스러운데 세 번째가 눈에 띄었다.
최고 기록이 눈에 띄었다
이 다섯이 특이했다.
bigwin_coin 최고 빅윈 코인
jackpot_coin 최고 잭팟 코인
bigwin_multiple 빅윈 배수
jackpot_multiple 잭팟 배수
max_coin 최고 보유 코인
전부 최고다. 이 값들은 로그에서 나오는데 max_coin 은 코인 로그의 tot_coin 최대값이고 bigwin_coin 은 스핀 로그의 당첨 최대값이라 MAX() 로 훑으면 구할 수 있다.
그런데도 저장돼 있다. 앞서 본 결제 총액과 같은 모양인데 매번 계산하면 로그 전체를 훑어야 하고 미리 저장하면 컬럼 하나만 읽는다. 최고 기록은 프로필이나 랭킹 화면에 자주 나오니 볼 때마다 로그 전체에 MAX() 를 돌릴 수는 없다.
갱신 조건이 다르다
다만 총액과 갱신 방식이 다르다. 총액은 매번 더하고 최고 기록은 더 크면 바꾼다.
if (새 값 > 기존 최고) { 기존 최고 = 새 값 }
대부분의 경우 안 바뀐다. 총액은 매 결제마다 UPDATE 가 돌고 최고 기록은 기록을 깰 때만 돈다.
UPDATE ... SET max_coin = ? WHERE max_coin < ? 한 문장이면 되고 대부분의 판에서는 ROW_COUNT() 가 0이다. 조건이 갱신문 안에 있으니 읽고 비교하는 왕복도 없다.
최고 기록은 갱신이 드물어서 저장해 두는 비용이 총액보다 작다. 같은 저장된 값이어도 갱신 조건이 다르면 비용이 다르다.
금액과 배수의 짝
bigwin_coin 과 bigwin_multiple 이 같이 있다. 앞의 것은 그때 딴 금액이고 뒤의 것은 그때의 배수라 두 값이 짝이다.
한쪽만 있으면 안 되는지 생각해 봤다. 코인만 있으면 10만 코인이라는 것은 알아도 베팅이 얼마였는지 모르고 배수만 있으면 500배라는 것은 알아도 실제 금액을 모른다.
둘이 다른 것을 말한다. 큰 금액은 베팅을 많이 해서 나올 수도 있고 큰 배수는 운이 좋았다는 뜻이라 자랑하는 지표가 다르다.
여기서 하나 걸렸다. 최고 금액이 나온 판과 최고 배수가 나온 판이 다를 수 있다.
판 A: 베팅 1000, 배수 100 → 금액 10만
판 B: 베팅 10, 배수 500 → 금액 5천
금액 최고는 A 이고 배수 최고는 B 다. 그러면 두 컬럼이 같은 판의 값인지 각각의 최고인지가 갈리는데 설계서만으로는 어느 쪽인지 모르겠다.
컬럼 설명이 bigwin_coin 은 빅윈 최고 금액이고 bigwin_multiple 은 빅윈 배수로만 돼 있다. 배수 쪽에는 최고가 안 붙어 있으니 금액이 최고인 판의 배수일 수도 있고 이것은 갱신 코드를 봐야 알 것 같다.
판단 기준 — 나눌지 말지
이 테이블을 나눈다면 신원과 현재 상태를 담는 user_info 와 최고 기록을 담는 user_record 로 갈릴 것이다. 행 크기가 줄고 자주 읽는 것과 가끔 읽는 것이 갈리며 InnoDB 가 한 페이지에 담는 행 수도 는다.
다만 나누면 조인이 는다. 프로필 화면은 신원과 상태와 기록을 다 보여주니 매번 JOIN 이고 함께 조회되는 것을 나누면 그 비용을 매번 낸다.
지금 지식으로는 어느 쪽이 나은지 모르겠다. 성격이 다르고 행이 작아진다는 것이 나누는 이유이고 같이 조회된다는 것이 안 나누는 이유인데 같이 조회되는지가 관건이라 실제 화면을 봐야 알 수 있을 것 같다.
정리
- 유저 테이블에 신원과 현재 상태와 누적 기록이 섞여 있다
- 최고 기록은 로그에
MAX()를 돌리면 나오는데 저장돼 있다 - 자주 읽히는 값이면 미리 계산해 두는 쪽이 낫다
- 총액은 매번 더하고 최고 기록은 기록을 깰 때만 갱신된다
UPDATE ... WHERE max_coin < ?한 문장이면 읽고 비교하는 왕복도 없다- 같은 저장 값이어도 갱신 조건이 다르면 비용이 다르다
- 금액과 배수가 짝으로 있고 둘이 다른 것을 말한다
- 최고 금액인 판과 최고 배수인 판이 다를 수 있다
- 설계서만으로는 어느 쪽인지 모르겠고 갱신 코드를 봐야 한다
- 성격으로 나누면 행이 작아지는데 같이 조회되면
JOIN이 는다