
1. 유저 테이블 (user)

유저의 기본 정보를 저장하는 테이블입니다.
- 컬럼 설명
- user_idx: 유저 인덱스 (BIGNINT UNSIGNED, 기본 키)
- 선택 이유:
BIGINT UNSIGNED
는 0 이상의 큰 숫자를 표현할 수 있으며, 유저 수가 많을 경우에도 충분한 범위를 제공합니다. 소규모 사이트라면 INT
를 사용할 수 있지만, 확장 가능성을 고려해 BIGINT
를 사용했습니다.
- email: 이메일 (VARCHAR(350), NOT NULL)
- 아이디 별로, 도메인 별로 글자 수 차이가 있고 최대 이메일의 길이가 300자 이상이라
VARCHAR(350)
로 설정했습니다.
- 다음 번에는 로그인 시 성능을 고려하고 중복을 방지하여 UNIQUE 키로 설정하고 싶습니다.
- password: 비밀번호 (CHAR(60), NOT NULL)
- 선택 이유: bcrypt로 암호화된 비밀번호는 고정된 60자의 길이를 가지므로
CHAR(60)
을 사용했습니다.
- created_at: 가입 일시 (TIMESTAMP, NOT NULL)
- updated_at: 수정 일시 (TIMESTAMP, NOT NULL)
- TIMESTAMP 선택 이유: 타임존이 고려되어 시간 정보를 저장할 수 있으며, 사이트가 글로벌 확장될 경우에도 시간대별로 정렬이 가능합니다. 또한 차지하는 메모리 공간이
DATETIME
보다 적기 때문에 TIMESTAMP
를 선택했습니다.
2. 결제 테이블 (payment)

결제 관련 정보를 관리하는 테이블입니다. 공통 결제 정보는 해당 테이블에 저장하고, 각 PG 사 별 상세 정보는 해당 테이블의 기본 키 정보를 가진 PG 사 별 테이블에 별도로 저장하도록 했습니다.
- payment_id: 결제 인덱스 (BIGNINT UNSIGNED, 기본 키)
- 선택 이유: 대규모 사이트에서도 결제 정보를 충분히 관리할 수 있도록
BIGINT UNSIGNED
를 사용했습니다.
- order_id: 주문 인덱스 (BIGNINT UNSIGNED, 유니크 키)
- 외래키 제약 조건을 피함으로써 결제와 주문 테이블 간의 독립성을 높이고, 테이블 변경 시 유연하게 대처할 수 있도록 유니크 키로 설정했습니다.
- state: 결제 상태 (TINYINT UNSIGNED, NOT NULL)
- 선택 이유: 결제 상태는 작은 숫자로 표현 가능하므로 공간 절약을 위해
TINYINT
를 사용했습니다. MySQL의 ENUM
을 사용할 때, 내부적으로 값이 숫자 인덱스로 매핑되기 때문에 잘못된 값이 삽입될 때 예상치 못한 동작이 발생할 수 있습니다. 즉, 잘못된 값이 들어가더라도 오류 없이 빈 문자열로 변환되거나 다른 값으로 해석될 수 있어 데이터 무결성을 해칠 위험이 있습니다. 또한 ENUM
은 표준 SQL 문법에 포함되지 않기 때문에 다른 DBMS에서는 지원되지 않는 경우가 많아 이식성 문제가 있습니다. 데이터베이스를 다른 시스템으로 이전할 때 ENUM
타입을 변환해야 하며, 이로 인해 추가적인 변환 작업과 복잡성이 발생할 수 있습니다.
- pg_company: PG 사 (TINYINT UNSIGNED, NOT NULL)
- total_amount: 총 결제 금액 (INT, NOT NULL)
- install_month: 할부 개월 수 (INT)
- payment_key: 각 PG사에서 발급한 결제키 (VARCHAR(200), NOT NULL)
- created_at: 결제 일시 (TIMESTAMP, NOT NULL)
- updated_at: 수정 일시 (TIMESTAMP, NOT NULL)