๐Ÿ’ป PROJECT/[Spring Boot, React] ๋…์„œ ์Šต๊ด€ ๊ด€๋ฆฌ ์„œ๋น„์Šค

[๋ฆฌํŒฉํ† ๋ง] JPA ์ธ๋ฑ์Šค ์ถ”๊ฐ€๋กœ ์กฐํšŒ ์„ฑ๋Šฅ ๊ฐœ์„ 

devCloud 2026. 5. 4. 10:55
728x90
 
REFACTORING

JPA ์ธ๋ฑ์Šค ์ถ”๊ฐ€๋กœ ์กฐํšŒ ์„ฑ๋Šฅ ๊ฐœ์„ ํ•˜๊ธฐ

1. ์ž‘์—… ๋ฐฐ๊ฒฝ

์ธ๋ฑ์Šค๋Š” DB๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์ „์ฒด ํ…Œ์ด๋ธ”์„ ์Šค์บ”ํ•˜์ง€ ์•Š๊ณ , ๋น ๋ฅด๊ฒŒ ์›ํ•˜๋Š” ํ–‰์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋‹ค.

 

WHERE ์กฐ๊ฑด์œผ๋กœ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด, ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์กฐํšŒ ์„ฑ๋Šฅ์ด ๊ธ‰๊ฒฉํžˆ ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค. ๋ฆฌํŒฉํ† ๋ง ๋‹จ๊ณ„์—์„œ ์ฟผ๋ฆฌ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜๋˜ ์ค‘ ์ž์ฃผ ์กฐํšŒ๋˜๋Š” ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ๊ณ , ์กฐํšŒ ์„ฑ๋Šฅ ๊ฐœ์„ ์„ ์œ„ํ•ด ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

์ด๋ฒˆ ์ž‘์—…์˜ ํ•ต์‹ฌ์€ ๋ชจ๋“  ์ปฌ๋Ÿผ์— ๋ฌด์ž‘์ • ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์‹ค์ œ ์กฐํšŒ ์กฐ๊ฑด์— ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ํ•„์š”ํ•œ ์ธ๋ฑ์Šค๋งŒ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

2. ์ ๊ฒ€ ๊ธฐ์ค€

์ธ๋ฑ์Šค ์ถ”๊ฐ€ ๋Œ€์ƒ์€ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” WHERE ์กฐ๊ฑด ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ์„ ์ •ํ–ˆ๋‹ค.

ํ…Œ์ด๋ธ” ์ปฌ๋Ÿผ ์ด์œ 
posts user_id ๊ฒŒ์‹œ๋ฌผ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ํ•ญ์ƒ WHERE ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
posts reading_status ๋…์„œ ์ƒํƒœ๋ณ„ ํ†ต๊ณ„ ์กฐํšŒ ์‹œ WHERE ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
posts completed_date ๊ธฐ๊ฐ„๋ณ„ ํ†ต๊ณ„ ์กฐํšŒ ์‹œ BETWEEN ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
memos post_id ํŠน์ • ๊ฒŒ์‹œ๋ฌผ์˜ ๋ฉ”๋ชจ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ํ•ญ์ƒ WHERE ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
reminders user_id ์‚ฌ์šฉ์ž๋ณ„ ๋ฆฌ๋งˆ์ธ๋” ์กฐํšŒ ์‹œ WHERE ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
reminders reminder_time ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ๋งค๋ถ„ ์•Œ๋ฆผ ๋Œ€์ƒ์„ ์กฐํšŒํ•  ๋•Œ WHERE ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

3. ์ธ๋ฑ์Šค ์ ์šฉ ์ „ ํ™•์ธ

๋จผ์ € H2์˜ INFORMATION_SCHEMA.INDEXES๋ฅผ ์กฐํšŒํ•ด์„œ ํ˜„์žฌ ํ…Œ์ด๋ธ”์— ์–ด๋–ค ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.

SELECT * FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = 'USERS';

H2์—์„œ USERS ํ…Œ์ด๋ธ”์˜ ์ธ๋ฑ์Šค ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ SQL์ด๋‹ค.

USERS ํ…Œ์ด๋ธ” ํ™•์ธ ๊ฒฐ๊ณผ, PK์ธ id์—๋งŒ ์ธ๋ฑ์Šค๊ฐ€ ์žกํ˜€ ์žˆ๊ณ  ๋ณ„๋„๋กœ ์ถ”๊ฐ€ํ•œ ์ธ๋ฑ์Šค๋Š” ์—†๋Š” ์ƒํƒœ์˜€๋‹ค.

 

์ด์–ด์„œ POSTS, MEMOS, REMINDERS ํ…Œ์ด๋ธ”๋„ ๋™์ผํ•˜๊ฒŒ ํ™•์ธํ–ˆ๋‹ค.

SELECT * FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = 'POSTS';
SELECT * FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = 'MEMOS';
SELECT * FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = 'REMINDERS';

POSTS, MEMOS, REMINDERS ํ…Œ์ด๋ธ”์˜ ์ธ๋ฑ์Šค ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ SQL์ด๋‹ค.

 

์„ธ ํ…Œ์ด๋ธ” ๋ชจ๋‘ PK ์ธ๋ฑ์Šค๋งŒ ์กด์žฌํ•˜๊ณ , WHERE ์กฐ๊ฑด์œผ๋กœ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿผ์—๋Š” ๋ณ„๋„ ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.


4. ์ ์šฉ ๋‚ด์šฉ

User ์—”ํ‹ฐํ‹ฐ

์ดˆ๊ธฐ์—๋Š” User ์—”ํ‹ฐํ‹ฐ์—๋งŒ @Table์˜ indexes ์†์„ฑ์œผ๋กœ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•ด๋‘” ์ƒํƒœ์˜€๋‹ค.

User ์—”ํ‹ฐํ‹ฐ์—๋งŒ ์ธ๋ฑ์Šค๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ๋˜ ์ดˆ๊ธฐ ์ฝ”๋“œ๋‹ค.

Post ์—”ํ‹ฐํ‹ฐ

Post ์—”ํ‹ฐํ‹ฐ๋Š” @Table ์–ด๋…ธํ…Œ์ด์…˜์— indexes ์†์„ฑ์ด ์—†์–ด ์ธ๋ฑ์Šค๊ฐ€ ์ „ํ˜€ ์ ์šฉ๋˜์ง€ ์•Š์€ ์ƒํƒœ์˜€๋‹ค.

์ธ๋ฑ์Šค ์ ์šฉ ์ „ Post ์—”ํ‹ฐํ‹ฐ ์ฝ”๋“œ๋‹ค.

@Table์— indexes ์†์„ฑ์ด ์—†์–ด ๋ณ„๋„ ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๋‹ค.

 

Post ์—”ํ‹ฐํ‹ฐ์— user_id, reading_status, completed_date ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ๋‹ค.

 

Memo ์—”ํ‹ฐํ‹ฐ

Memo ์—”ํ‹ฐํ‹ฐ์—๋Š” ํŠน์ • ๊ฒŒ์‹œ๋ฌผ์˜ ๋ฉ”๋ชจ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” post_id ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

@Table(name = "memos", indexes = {
    @Index(name = "idx_memos_post_id", columnList = "post_id")
})

Memo ์—”ํ‹ฐํ‹ฐ์— post_id ์ปฌ๋Ÿผ ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ๋‹ค.

 

Reminder ์—”ํ‹ฐํ‹ฐ

Reminder ์—”ํ‹ฐํ‹ฐ์—๋Š” ์‚ฌ์šฉ์ž๋ณ„ ๋ฆฌ๋งˆ์ธ๋” ์กฐํšŒ์— ์‚ฌ์šฉ๋˜๋Š” user_id์™€, ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ๋งค๋ถ„ ์•Œ๋ฆผ ๋Œ€์ƒ์„ ์ฐพ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” reminder_time ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

@Table(name = "reminders", indexes = {
    @Index(name = "idx_reminders_user_id", columnList = "user_id"),
    @Index(name = "idx_reminders_reminder_time", columnList = "reminder_time")
})

Reminder ์—”ํ‹ฐํ‹ฐ์— user_id์™€ reminder_time ์ปฌ๋Ÿผ ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ๋‹ค.


5. ์ ์šฉ ํ›„ ํ™•์ธ

์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ๋’ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ณ , H2์—์„œ ์ธ๋ฑ์Šค๊ฐ€ ์‹ค์ œ๋กœ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ–ˆ๋‹ค.

์ธ๋ฑ์Šค ์ ์šฉ ํ›„ user_id, reading_status, completed_date ๋“ฑ ์ถ”๊ฐ€ํ•œ ์ปฌ๋Ÿผ๋“ค์— ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.

JPA์˜ @Index ์„ค์ •์€ ์—”ํ‹ฐํ‹ฐ ์ฝ”๋“œ์— ์„ ์–ธํ–ˆ๋‹ค๊ณ  ๋๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์‹ค์ œ DB์— ์›ํ•˜๋Š” ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •๊นŒ์ง€ ํ•จ๊ป˜ ํ•„์š”ํ•˜๋‹ค.

6. ์ฐธ๊ณ 

  • jakarta.persistence.Index import๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
  • ๋กœ์ปฌ H2 ํ™˜๊ฒฝ์—์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์žฌ์‹œ์ž‘ ์‹œ ์ž๋™์œผ๋กœ ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.
  • ์šด์˜ MySQL ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฐฐํฌ ์‹œ DDL ์ ์šฉ ๋ฐฉ์‹์„ ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
  • ์ธ๋ฑ์Šค๋Š” ์กฐํšŒ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, insert/update ์‹œ ์ธ๋ฑ์Šค๋„ ํ•จ๊ป˜ ๊ฐฑ์‹ ๋˜๋ฏ€๋กœ ์“ฐ๊ธฐ ์„ฑ๋Šฅ์—๋Š” ๋น„์šฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

7. ๋ฐฐ์šด ์ 

์ธ๋ฑ์Šค๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ์ปฌ๋Ÿผ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์‹ค์ œ๋กœ WHERE ์กฐ๊ฑด์— ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ์ปฌ๋Ÿผ์„ ํŒŒ์•…ํ•œ ๋’ค ์„ ํƒ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

 

์ธ๋ฑ์Šค๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์กฐํšŒ ์„ฑ๋Šฅ์€ ์ข‹์•„์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, insert/update ์‹œ ์ธ๋ฑ์Šค๋„ ํ•จ๊ป˜ ๊ฐฑ์‹ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๊ธฐ ์„ฑ๋Šฅ์€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์กฐํšŒ ํŒจํ„ด๊ณผ ์“ฐ๊ธฐ ๋นˆ๋„๋ฅผ ํ•จ๊ป˜ ๊ณ ๋ คํ•ด์„œ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

๋˜ํ•œ H2์˜ INFORMATION_SCHEMA.INDEXES๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ์ ์šฉ๋œ ์ธ๋ฑ์Šค๋ฅผ ์ง์ ‘ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ๋กœ์ปฌ์—์„œ JPA ์—”ํ‹ฐํ‹ฐ ์„ค์ •์ด ์‹ค์ œ DB์— ๋ฐ˜์˜๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด, ์ธ๋ฑ์Šค๋Š” “๋งŽ์„์ˆ˜๋ก ์ข‹์€ ์„ค์ •”์ด ์•„๋‹ˆ๋ผ ์‹ค์ œ ์กฐํšŒ ์กฐ๊ฑด๊ณผ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๋น„์šฉ์„ ํ•จ๊ป˜ ๊ณ ๋ คํ•ด์„œ ์„ ํƒ์ ์œผ๋กœ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ์„ฑ๋Šฅ ๊ฐœ์„  ๋„๊ตฌ๋‹ค.
728x90