Skip to content

Commit 5c6ee39

Browse files
authored
Merge pull request #345 from EAT-SSU/develop
feat: DB λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 및 Flyway μžλ™ν™” 적용
2 parents 2eacfad + d66e77a commit 5c6ee39

12 files changed

Lines changed: 763 additions & 2 deletions

β€ŽMIGRATION_GUIDE.mdβ€Ž

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# DB λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹€ν–‰ κ°€μ΄λ“œ
2+
3+
## πŸ“ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 파일 λͺ©λ‘
4+
5+
```
6+
src/main/resources/db/migration/
7+
β”œβ”€β”€ V2__align_pk_and_fk_types.sql (PK/FK bigint 톡일)
8+
β”œβ”€β”€ V3__convert_varchar_to_enum.sql (varchar β†’ enum λ³€ν™˜)
9+
└── V4__add_constraints_and_defaults.sql (μ œμ•½μ‘°κ±΄ 및 κΈ°λ³Έκ°’)
10+
```
11+
12+
## πŸš€ μ‹€ν–‰ μˆœμ„œ
13+
14+
### 1️⃣ 사전 μ€€λΉ„ (ν•„μˆ˜)
15+
16+
#### βœ… μŠ€λƒ…μƒ· 확인
17+
- [ ] Dev DB μŠ€λƒ…μƒ· 생성 μ™„λ£Œ
18+
- [ ] Prod DB μŠ€λƒ…μƒ· 생성 μ™„λ£Œ (μ‹€μ œ 배포 μ „)
19+
20+
#### βœ… 데이터 검증 (ν•„μˆ˜)
21+
```bash
22+
# varchar 데이터가 Enumκ³Ό μΌμΉ˜ν•˜λŠ”μ§€ 검증
23+
./run_validation.sh
24+
```
25+
26+
**μ€‘μš”:** 검증 κ²°κ³Όκ°€ λΉ„μ–΄μžˆμ–΄μ•Ό 정상 (뢈일치 데이터 μ—†μŒ)
27+
28+
#### βœ… FK μ œμ•½μ‘°κ±΄λͺ… 확인 (선택)
29+
```bash
30+
# department, partnership의 FK 이름 확인
31+
mysql -h <host> -u <user> -p <database> < check_fk_constraints.sql
32+
```
33+
34+
---
35+
36+
### 2️⃣ Dev ν™˜κ²½ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
37+
38+
#### 방법 1: Flyway μžλ™ μ‹€ν–‰ (ꢌμž₯)
39+
```bash
40+
# application-dev.yml의 spring.flyway μ„€μ • 확인
41+
# spring.jpa.hibernate.ddl-auto: none 확인
42+
43+
# μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ μ‹œ μžλ™μœΌλ‘œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹€ν–‰
44+
./gradlew bootRun --args='--spring.profiles.active=dev'
45+
```
46+
47+
#### 방법 2: μˆ˜λ™ μ‹€ν–‰
48+
```bash
49+
# V2 μ‹€ν–‰
50+
mysql -h <host> -u <user> -p <database> < src/main/resources/db/migration/V2__align_pk_and_fk_types.sql
51+
52+
# 검증: PK/FK νƒ€μž… 확인
53+
mysql -h <host> -u <user> -p -e "
54+
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
55+
FROM information_schema.COLUMNS
56+
WHERE TABLE_SCHEMA = '<database>'
57+
AND COLUMN_NAME IN ('college_id', 'department_id')
58+
ORDER BY TABLE_NAME;
59+
"
60+
61+
# V3 μ‹€ν–‰
62+
mysql -h <host> -u <user> -p <database> < src/main/resources/db/migration/V3__convert_varchar_to_enum.sql
63+
64+
# 검증: Enum νƒ€μž… 확인
65+
mysql -h <host> -u <user> -p -e "
66+
SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE
67+
FROM information_schema.COLUMNS
68+
WHERE TABLE_SCHEMA = '<database>'
69+
AND DATA_TYPE = 'enum'
70+
ORDER BY TABLE_NAME;
71+
"
72+
73+
# V4 μ‹€ν–‰
74+
mysql -h <host> -u <user> -p <database> < src/main/resources/db/migration/V4__add_constraints_and_defaults.sql
75+
76+
# 검증: μ œμ•½μ‘°κ±΄ 확인
77+
mysql -h <host> -u <user> -p -e "
78+
SHOW CREATE TABLE college;
79+
SHOW CREATE TABLE menu;
80+
SHOW CREATE TABLE review;
81+
"
82+
```
83+
84+
---
85+
86+
### 3️⃣ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 검증
87+
88+
#### μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν…ŒμŠ€νŠΈ
89+
```bash
90+
# μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μž¬μ‹œμž‘
91+
./gradlew bootRun --args='--spring.profiles.active=dev'
92+
93+
# 둜그 확인
94+
# - Enum λ§€ν•‘ 였λ₯˜ μ—†λŠ”μ§€
95+
# - DB μ—°κ²° 정상인지
96+
# - API 호좜 정상인지
97+
```
98+
99+
#### DB 데이터 확인
100+
```sql
101+
-- Enum κ°’ 쑰회 ν…ŒμŠ€νŠΈ
102+
SELECT restaurant, time_part FROM meal LIMIT 10;
103+
SELECT provider, role, status FROM user LIMIT 10;
104+
105+
-- PK/FK νƒ€μž… 확인
106+
SELECT
107+
TABLE_NAME,
108+
COLUMN_NAME,
109+
DATA_TYPE,
110+
COLUMN_TYPE
111+
FROM information_schema.COLUMNS
112+
WHERE TABLE_SCHEMA = '<database>'
113+
AND COLUMN_NAME IN ('college_id', 'department_id')
114+
ORDER BY TABLE_NAME, COLUMN_NAME;
115+
116+
-- μ œμ•½μ‘°κ±΄ 확인
117+
SELECT
118+
TABLE_NAME,
119+
CONSTRAINT_NAME,
120+
CONSTRAINT_TYPE
121+
FROM information_schema.TABLE_CONSTRAINTS
122+
WHERE TABLE_SCHEMA = '<database>'
123+
AND TABLE_NAME IN ('college', 'menu', 'review');
124+
```
125+
126+
---
127+
128+
### 4️⃣ Prod ν™˜κ²½ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
129+
130+
#### μ‹€ν–‰ μ „ 체크리슀트
131+
- [ ] Dev ν™˜κ²½ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ™„λ£Œ 및 검증
132+
- [ ] Dev ν™˜κ²½ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 정상 λ™μž‘ 확인
133+
- [ ] Prod DB μŠ€λƒ…μƒ· 생성 μ™„λ£Œ
134+
- [ ] 데이터 검증 (validate_enum_data.sql) μ™„λ£Œ
135+
- [ ] μ‚¬μš©λŸ‰μ΄ 적은 μ‹œκ°„λŒ€ 선택 (μƒˆλ²½ 2-4μ‹œ ꢌμž₯)
136+
- [ ] λ‘€λ°± κ³„νš 수립
137+
138+
#### μ‹€ν–‰
139+
```bash
140+
# Prod ν™˜κ²½μ—μ„œ λ™μΌν•˜κ²Œ μ‹€ν–‰
141+
./gradlew bootRun --args='--spring.profiles.active=prod'
142+
143+
# λ˜λŠ” μˆ˜λ™ μ‹€ν–‰
144+
mysql -h <prod-host> -u <user> -p <database> < V2__align_pk_and_fk_types.sql
145+
mysql -h <prod-host> -u <user> -p <database> < V3__convert_varchar_to_enum.sql
146+
mysql -h <prod-host> -u <user> -p <database> < V4__add_constraints_and_defaults.sql
147+
```
148+
149+
---
150+
151+
## ⚠️ μ£Όμ˜μ‚¬ν•­
152+
153+
### 1. metadata lock λ°©μ§€
154+
- μ‚¬μš©λŸ‰μ΄ 적은 μ‹œκ°„λŒ€μ— μ‹€ν–‰
155+
- μ‹€ν–‰ 쀑 λ‹€λ₯Έ μ„Έμ…˜μ—μ„œ DDL μž‘μ—… κΈˆμ§€
156+
157+
### 2. 데이터 검증 ν•„μˆ˜
158+
```bash
159+
# V3 μ‹€ν–‰ μ „ λ°˜λ“œμ‹œ 검증
160+
./run_validation.sh
161+
```
162+
163+
### 3. FK μ œμ•½μ‘°κ±΄ 처리
164+
- V2μ—μ„œ `SET FOREIGN_KEY_CHECKS = 0/1` μ‚¬μš©
165+
- FK μ œμ•½μ‘°κ±΄μ€ μžλ™μœΌλ‘œ μœ μ§€λ¨
166+
167+
### 4. λ‘€λ°± 방법
168+
```bash
169+
# AWS RDS μŠ€λƒ…μƒ·μœΌλ‘œ 볡원
170+
aws rds restore-db-instance-from-db-snapshot \
171+
--db-instance-identifier your-db-restored \
172+
--db-snapshot-identifier eatssu-dev-pre-migration-20260207
173+
```
174+
175+
---
176+
177+
## πŸ› 문제 λ°œμƒ μ‹œ
178+
179+
### 1. Enum λ³€ν™˜ μ‹€νŒ¨
180+
```
181+
ERROR 1265: Data truncated for column 'restaurant' at row 1
182+
```
183+
**원인:** DB에 Enum에 μ—†λŠ” 값이 쑴재
184+
**ν•΄κ²°:** `validate_enum_data.sql` μ‹€ν–‰ν•˜μ—¬ 뢈일치 데이터 μ°ΎκΈ°
185+
186+
### 2. PK νƒ€μž… λ³€κ²½ μ‹€νŒ¨
187+
```
188+
ERROR 1833: Cannot change column: used in a foreign key constraint
189+
```
190+
**원인:** FK μ œμ•½μ‘°κ±΄μ΄ 걸렀있음
191+
**ν•΄κ²°:** V2 νŒŒμΌμ— `SET FOREIGN_KEY_CHECKS = 0` 이미 포함됨
192+
193+
### 3. unique μ œμ•½μ‘°κ±΄ μ‹€νŒ¨
194+
```
195+
ERROR 1062: Duplicate entry for key 'UK_college_name'
196+
```
197+
**원인:** college.name에 쀑볡 데이터 쑴재
198+
**ν•΄κ²°:** 쀑볡 데이터 정리 ν›„ λ‹€μ‹œ μ‹€ν–‰
199+
200+
---
201+
202+
## βœ… μ™„λ£Œ 확인
203+
204+
- [ ] V2, V3, V4 λͺ¨λ‘ 정상 μ‹€ν–‰
205+
- [ ] flyway_schema_history ν…Œμ΄λΈ”μ— 기둝 확인
206+
- [ ] μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 정상 λ™μž‘ 확인
207+
- [ ] API ν…ŒμŠ€νŠΈ 톡과
208+
- [ ] λ‘œκ·Έμ— 였λ₯˜ μ—†μŒ

β€Žbuild.gradleβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ repositories {
3131

3232
dependencies {
3333
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
34+
implementation 'org.flywaydb:flyway-core'
35+
implementation 'org.flywaydb:flyway-mysql'
3436
implementation 'org.springframework.boot:spring-boot-starter-web'
3537
implementation 'org.jetbrains:annotations:20.1.0'
3638
implementation 'org.springframework.boot:spring-boot-starter-security'

β€Žcheck_fk_constraints.sqlβ€Ž

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
-- =========================
2+
-- FK μ œμ•½μ‘°κ±΄λͺ… 확인
3+
-- =========================
4+
-- μ‹€ν–‰ 방법: mysql -h <host> -u <user> -p <database> < check_fk_constraints.sql
5+
6+
-- department, partnership ν…Œμ΄λΈ”μ˜ FK μ œμ•½μ‘°κ±΄ 확인
7+
SELECT
8+
CONSTRAINT_NAME AS 'FK 이름',
9+
TABLE_NAME AS 'ν…Œμ΄λΈ”',
10+
COLUMN_NAME AS '컬럼',
11+
REFERENCED_TABLE_NAME AS 'μ°Έμ‘° ν…Œμ΄λΈ”',
12+
REFERENCED_COLUMN_NAME AS '참쑰 컬럼'
13+
FROM information_schema.KEY_COLUMN_USAGE
14+
WHERE TABLE_SCHEMA = DATABASE()
15+
AND REFERENCED_TABLE_NAME IS NOT NULL
16+
AND TABLE_NAME IN ('department', 'partnership')
17+
ORDER BY TABLE_NAME, CONSTRAINT_NAME;
18+
19+
-- =========================
20+
-- 전체 FK μ œμ•½μ‘°κ±΄ 확인 (참고용)
21+
-- =========================
22+
SELECT
23+
TABLE_NAME AS 'ν…Œμ΄λΈ”',
24+
CONSTRAINT_NAME AS 'FK 이름',
25+
COLUMN_NAME AS '컬럼',
26+
REFERENCED_TABLE_NAME AS 'μ°Έμ‘° ν…Œμ΄λΈ”',
27+
REFERENCED_COLUMN_NAME AS '참쑰 컬럼'
28+
FROM information_schema.KEY_COLUMN_USAGE
29+
WHERE TABLE_SCHEMA = DATABASE()
30+
AND REFERENCED_TABLE_NAME IS NOT NULL
31+
ORDER BY TABLE_NAME, CONSTRAINT_NAME;

β€Žrun_validation.shβ€Ž

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
3+
# =========================
4+
# Enum 데이터 검증 슀크립트
5+
# =========================
6+
7+
echo "=========================================="
8+
echo "Enum 데이터 검증 μ‹œμž‘"
9+
echo "=========================================="
10+
echo ""
11+
12+
# μ‚¬μš©μžμ—κ²Œ ν™˜κ²½ 선택
13+
read -p "검증할 ν™˜κ²½μ„ μ„ νƒν•˜μ„Έμš” (dev/prod): " ENV
14+
15+
if [ "$ENV" != "dev" ] && [ "$ENV" != "prod" ]; then
16+
echo "였λ₯˜: 'dev' λ˜λŠ” 'prod'만 μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€."
17+
exit 1
18+
fi
19+
20+
# DB 접속 정보 μž…λ ₯
21+
read -p "DB 호슀트λ₯Ό μž…λ ₯ν•˜μ„Έμš”: " DB_HOST
22+
read -p "DB μ‚¬μš©μžλͺ…을 μž…λ ₯ν•˜μ„Έμš”: " DB_USER
23+
read -sp "DB λΉ„λ°€λ²ˆν˜Έλ₯Ό μž…λ ₯ν•˜μ„Έμš”: " DB_PASS
24+
echo ""
25+
read -p "DB 이름을 μž…λ ₯ν•˜μ„Έμš”: " DB_NAME
26+
27+
echo ""
28+
echo "[$ENV ν™˜κ²½] 데이터 검증을 μ‹œμž‘ν•©λ‹ˆλ‹€..."
29+
echo ""
30+
31+
# 검증 쿼리 μ‹€ν–‰
32+
RESULT_FILE="validation_result_${ENV}_$(date +%Y%m%d_%H%M%S).txt"
33+
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" < validate_enum_data.sql > "$RESULT_FILE" 2>&1
34+
35+
if [ $? -eq 0 ]; then
36+
echo "βœ… 검증 μ™„λ£Œ! κ²°κ³Ό νŒŒμΌμ„ ν™•μΈν•˜μ„Έμš”: $RESULT_FILE"
37+
echo ""
38+
echo "⚠️ μ€‘μš”: κ²°κ³Ό νŒŒμΌμ—μ„œ μ•„λž˜ λ‚΄μš©μ„ ν™•μΈν•˜μ„Έμš”"
39+
echo " - 뢈일치 데이터가 μžˆλŠ” 경우: 데이터 정리 ν›„ λ‹€μ‹œ 검증"
40+
echo " - κ²°κ³Όκ°€ λΉ„μ–΄μžˆλŠ” 경우: varchar β†’ enum λ³€ν™˜ μ§„ν–‰ κ°€λŠ₯"
41+
echo ""
42+
else
43+
echo "❌ 검증 μ‹€νŒ¨. 접속 정보λ₯Ό ν™•μΈν•˜μ„Έμš”."
44+
exit 1
45+
fi

β€Žsrc/main/resources/application-dev.ymlβ€Ž

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ server:
55

66

77
spring:
8+
## Flyway
9+
flyway:
10+
enabled: true
11+
baseline-on-migrate: true
12+
baseline-version: 1
13+
locations: classpath:db/migration
14+
815
## Database
916
datasource:
1017
driver-class-name: com.mysql.cj.jdbc.Driver
@@ -41,8 +48,8 @@ spring:
4148
jwt:
4249
secret:
4350
key: ${EATSSU_JWT_SECRET_DEV}
44-
token-validity-in-seconds: 60
45-
refresh-token-validity-in-seconds: 180
51+
token-validity-in-seconds: 86400
52+
refresh-token-validity-in-seconds: 604800
4653

4754
#S3
4855
cloud:

β€Žsrc/main/resources/application-prod.ymlβ€Ž

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ server:
55

66

77
spring:
8+
## Flyway
9+
flyway:
10+
enabled: true
11+
baseline-on-migrate: true
12+
baseline-version: 1
13+
locations: classpath:db/migration
14+
815
## Database
916
datasource:
1017
driver-class-name: com.mysql.cj.jdbc.Driver

0 commit comments

Comments
Β (0)