MySQL 설계
요구사항 분석
•
이벤트 기간 내에 발급 (예시: 2024-01-01 09:00 ~ 2024-01-08 17:00)
•
선착순 쿠폰의 최대 쿠폰 발급 수량 설정 : 30,000건
•
선착순 이벤트는 유저당 1번의 쿠폰 발급
요구사항을 행동을 분석하면 크게 2가지로 나뉘며 이에 따라 테이블을 구별하였다.
1.
쿠폰 정책 검증 (coupon 테이블)
•
쿠폰이 요구사항(기간검증, 수량검증)에 맞는지 확인한다.
•
검증 조건을 통과한 경우에만 발급이 가능하다.
2.
발급된 내역을 관리 (coupon-issues 테이블)
•
발급된 쿠폰을 기록하여, 발급 상태를 추적하고 중복 발급을 방지한다.
•
중복검증은 발급된 내역에서 확인한다.
테이블 | 필드 | |
기간검증 | coupons | date_issue_start, date_issue_end |
수량검증 | coupons | issued_quantity, total_quantity |
중복검증 | coupon_issues | user_id, coupon_id |
쿠폰 정책 검증 (coupon 테이블)
coupon 테이블은 쿠폰 정책 및 발급 가능 여부를 관리한다.
•
쿠폰의 기본정책 정의(쿠폰, 발급 기간, 최대 수량 등)
•
기간검증: date_issue_start, date_issue_end 필드를 사용하여 기간을 검증
•
수량검증: total_quantity, issued_quantity 필드로 발급 가능 수량 검증
-- coupon 테이블
CREATE TABLE `coupon`.`coupons`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL COMMENT '쿠폰명',
`coupon_type` VARCHAR(255) NOT NULL COMMENT '쿠폰 타입 (선착순 쿠폰, ..)',
`total_quantity` INT NULL COMMENT '쿠폰 발급 최대 수량',
`issued_quantity` INT NOT NULL COMMENT '발급된 쿠폰 수량',
`discount_amount` INT NOT NULL COMMENT '할인 금액',
`min_available_amount` INT NOT NULL COMMENT '최소 사용 금액',
`date_issue_start` datetime(6) NOT NULL COMMENT '발급 시작 일시',
`date_issue_end` datetime(6) NOT NULL COMMENT '발급 종료 일시',
`date_created` datetime(6) NOT NULL COMMENT '생성 일시',
`date_updated` datetime(6) NOT NULL COMMENT '수정 일시',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT '쿠폰 정책';
SQL
복사
발급된 내역을 관리 (coupon-issues 테이블)
coupon-issues 테이블은 쿠폰 발급 내역을 관리하며 중복 발급을 방지한다.
•
쿠폰 발급 내역관리 (누가, 언제, 어떤 쿠폰을 발급 받았는지 기록)
•
couponId, userId로 발급 이력을 관리
CREATE TABLE `coupon`.`coupon_issues`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`coupon_id` BIGINT(20) NOT NULL COMMENT '쿠폰 ID',
`user_id` BIGINT(20) NOT NULL COMMENT '유저 ID',
`date_issued` datetime(6) NOT NULL COMMENT '발급 일시',
`date_used` datetime(6) NULL COMMENT '사용 일시',
`date_created` datetime(6) NOT NULL COMMENT '생성 일시',
`date_updated` datetime(6) NOT NULL COMMENT '수정 일시',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT '쿠폰 발급 내역';
SQL
복사
도커 컴포즈
•
docker-compose.yml
version: '3.7'
services:
mysql:
container_name: coupon-mysql
image: ubuntu/mysql:edge
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=1234
- MYSQL_DATABASE=coupon
- MYSQL_USER=abcd
- MYSQL_PASSWORD=1234
- TZ=UTC
redis:
container_name: coupon-redis
image: redis:7.2-alpine
ports:
- 6379:6379
labels:
- "name=redis"
- "mode=standalone"
Java
복사
mysql 서비스 설정:
container_name | 컨테이너 이름을 coupon-mysql로 명시적으로 지정
컨테이너 이름을 명확히 설정하면 네트워크에서 서비스 간 참조가 쉬움 |
image | 컨테이너 이미지는 ubuntu/mysql:edge를 사용 |
ports | ”3306:3306” (포트포워딩 설정O)
- 호스트포트:컨테이너포트
- 포트포워딩을 통해 호스트에서 컨테이너 내부 MySQL에 연결가능
- 외부 접근이 필요하면 3306:3306으로 설정
- 개발환경이나 테스트 환경에서 유용
”3306” (포트포워딩 설정X)
- 컨테이너 내부의 3306 포트만 열림
- 호스트와 외부 네트워크에서 MySQL 직접 접근 불가
- 컨테이너 간 통신에 제한이 없어 내부에서만 접근 가능
- 외부 노출이 없으므로 보안성 높다.
- 호스트나 외부에서 접근하려면 추가설정 필요
- 프로덕션 환경에서는 포트를 외부로 노출하지 않는것을 권장 |
environment | - MYSQL_ROOT_PASSWORD: (필수)MySQL root 사용자 계정의 비밀번호 설정
- MYSQL_DATABASE: 초기화할 데이터베이스 이름을 지정
- MYSQL_USER 및 MYSQL_PASSWORD: 사용자 계정 생성 및 인증 정보 설정
- MYSQL_ROOT_PASSWORD: MySQL root 사용자 계정의 비밀번호 설정
- TZ: 타임존을 UTC로 설정 |
redis 서비스 설정:
container_name | 컨테이너 이름을 명시적으로 지정
네트워크에서 다른 컨테이너가 Redis를 참조할 때 가독성이 높아지고 관리가 용이
다른 서비스가 Redis에 접근할 때 coupon-redis를 바로 사용할 수 있음 |
image | Redis의 7.2 버전을 alpine 기반 경량 이미지로 실행
- 7.2버전: Redis의 최신 안정 버전으로, 최신 기능과
- alpine: 경량 이미지로, 디스크 공간을 적게 사용하고 빠른 실행 속도 제공
- Redis는 단순한 Key-Value Store이므로 경량 이미지를 사용하는 것이 최적 |
ports | 호스트의 6379 포트와 컨테이너의 6379 포트를 매핑 |
command | - redis-server --port 6379:
컨테이너 내부에서 Redis 서버를 6379 포트로 실행
Redis는 기본적으로 6379 포트를 사용하며, 이를 명시적으로 설정하여 유지보수성과 가독성을 높임
필요에 따라 다른 포트를 지정하려면 이 값을 변경할 수 있음 |
labels | Redis 컨테이너에 메타데이터(레이블)를 추가
- name=redis: 서비스 이름을 메타데이터로 저장하여 모니터링 도구
(예: Prometheus, Docker Dashboard 등)에서 컨테이너를 식별 가능
- mode=standalone: Redis가 단독(Standalone) 모드로 동작하고 있음을 명시
이는 Redis가 클러스터 모드가 아닌 단일 노드로 실행됨을 나타낸다.
설정을 통해 Redis 클러스터가 필요하지 않은 간단한 환경에서 사용 |
도커 컴포즈 실행 및 확인
컨테이너 실행
docker-compose up -d
docker ps -a
Java
복사
컨테이너 실행 확인
MySQL
•
확인방법1: 컨테이너 내부
> docker logs coupon-mysql
> docker exec -it coupon-mysql /bin/bash
# mysql -u abcd -p
Enter password: 1234
mysql> show databases;
mysql> use coupon;
mysql> show tables;
Java
복사
쿠폰서비스 테이블 : 2개
카카오쇼핑 적용 후 테이블 : 총8개
Tip: MySQL 원격접속 명령어 사용하기
mysql -h <호스트명> -P <포트번호> -u <사용자명> -p
mysql -h coupon-mysql -P 3306 -u abcd -p
SQL
복사
◦
-h: 접속할 MySQL서버의 호스트명 또는 IP주소를 지정
▪
IP주소: 192.168.x.x
▪
호스트명: example.com, localhost, 컨테이너이름
•
확인방법2: DBMS 도구로 연결
DB관리도구 (예: DBeaver, DataGrip)에서 MySQL 서버에 연결하여 확인한다.
Redis
•
확인방법 1: 컨테이너 내부
❯ docker exec -it coupon-redis redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set a 1
127.0.0.1:6379> get a
"1"
Java
복사
•
확인방법2: DBMS 도구로 연결
DB관리도구 (예: DBeaver, DataGrip)에서 Redis 서버에 연결하여 확인한다.
Host | |
Port | 6379 |
Related Posts
Search