Skip to content

Trouble Shooting

LeeJuHyun edited this page Sep 17, 2022 · 26 revisions

๐Ÿ“Ž ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘ ๋ฐœ์ƒํ–ˆ๋˜ ์ด์Šˆ๋“ค์— ๋Œ€ํ•ด ์ •๋ฆฌํ•œ Wiki

  • ์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ
  • ๊ฐœ๋… & ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•(์„ ํƒํ•œ ์ด์œ )
  • ์ฐธ๊ณ ๋ฌธ์„œ

๐Ÿ’ก ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฆฌํŒฉํ† ๋ง ๋ฐ ๋””์ž์ธ ํŒจํ„ด ์ ์šฉ๊ธฐ - ์ฃผํ˜„


๐Ÿ’ก JPA N+1 - ์ฃผํ˜„


๐Ÿ’ก Join vs Subquery - ์ง€ํ™˜

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

โ†’ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์€ ๋‘ ๊ธฐ๋Šฅ์ด ๋ฌด์Šจ ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€?

โ†’ ์„ฑ๋Šฅ ์ƒ์˜ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ถ๊ธˆ์ฆ

์ฐจ์ด์ ๊ณผ ์‚ฌ์šฉ๋ฒ•(๊ฐœ๋…)

ํ•œ์ค„๋กœ ์š”์•ฝํ•ด๋ณด๋ฉด, ๋  ์ˆ˜ ์žˆ์œผ๋ฉด join์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์„ฑ๋Šฅ์ ์œผ๋กœ ์ข‹๋‹ค.

subquery์˜ ๊ฒฝ์šฐ์—๋Š” ๋‚ด๋ถ€ ์ฟผ๋ฆฌ๋งŒ์œผ๋กœ๋Š” ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€ ์ฟผ๋ฆฌ๋ฌธ์— ์˜์กดํ•ด์•ผํ•œ๋‹ค!

SELECT
 name,
 cost
FROM product
WHERE id =
( SELECT product_id
   FROM sale
   WHERE price = 2000
        AND product_id = product.id );

price๊ฐ€ 2000์ธ ์นœ๊ตฌ๋“ค์„ ๊ฒ€์ƒ‰ํ•˜๋Š” subquery๋Š” ์™ธ๋ถ€์˜ product.id๋ฅผ ๊ณ„์†ํ•ด์„œ ์ฐธ์กฐํ•ด์•ผํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•œ๋ฒˆ์— ๋‘๊ฐœ๋ฅผ ๋ชจ๋‘ ๋“ค๊ณ ์™€์„œ ์—ฐ์‚ฐํ•˜๋Š” join๋ณด๋‹ค๋Š” ์„ฑ๋Šฅ์ ์œผ๋กœ ์•ˆ์ข‹์„ ์ˆ˜๋ฐ–์— ์—†๋‹ค.

ํ•˜์ง€๋งŒ, subquery๋งŒ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋“ค์ด ์กด์žฌํ•œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด join์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค๊ณผ subquery๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์„ ์ •๋ฆฌํ•ด๋ณด์ž!

join๊ณผ subquery๋ฌธ ๋‘˜๋‹ค ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ โ†’ join์„ ์‚ฌ์šฉํ•˜์ž!

์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ

โ†’ ๊ทธ๋ƒฅ join์œผ๋กœ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

IN ์—ฐ์‚ฐ์ž ์•ˆ์— ์žˆ๋Š” ์„œ๋ธŒ ์ฟผ๋ฆฌ

โ†’ ๊ทธ๋ƒฅ join์œผ๋กœ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

NOT IN ์—ฐ์‚ฐ์ž ์•ˆ์— ์žˆ๋Š” ์„œ๋ธŒ ์ฟผ๋ฆฌ

โ†’ NOT ๋Œ€์‹  NULL์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ join์œผ๋กœ ๋ณ€๊ฒฝํ•˜์ž, JOINํ•˜๋Š” ์œ„์น˜๋ฅผ ์ž˜ ์ง€์ •ํ•ด์„œ JOINํ•ด์ฃผ์ž

EXISTS, NOT EXISTS ์—ฐ์‚ฐ์ž ์•ˆ์˜ ์ƒ๊ด€๊ด€๊ณ„ ์„œ๋ธŒ ์ฟผ๋ฆฌ

โ†’ NOT ๋Œ€์‹  NULL์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ join์œผ๋กœ ๋ณ€๊ฒฝํ•˜์ž, JOINํ•˜๋Š” ์œ„์น˜๋ฅผ ์ž˜ ์ง€์ •ํ•ด์„œ JOINํ•ด์ฃผ์ž

subquery๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ์ฟผ๋ฆฌ

GROUP BY๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ FROM ์ ˆ์— ์žˆ์„ ๋•Œ

์ง‘๊ณ„๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ WHERE ์ ˆ์— ์žˆ์„ ๋•Œ

์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ ALL ์—ฐ์‚ฐ์ž์— ์žˆ์„ ๋•Œ

  • ์™ผ์ชฝ: join, ์˜ค๋ฅธ์ชฝ: Subquery image

์ฐธ๊ณ ์ž๋ฃŒ

https://kimsyoung.tistory.com/entry/SUBQUERY-์™€-JOIN-์˜-์ฐจ์ด-ไธŠ

https://kimsyoung.tistory.com/entry/SUBQUERY-์™€-JOIN-์˜-์ฐจ์ด-ไธ‹

https://kimsyoung.tistory.com/entry/์„œ๋ธŒ-์ฟผ๋ฆฌ์˜-์ข…๋ฅ˜์—๋Š”-๋ฌด์—‡์ด-์žˆ์„๊นŒ


๐Ÿ’ก GitHub-Actions๋ฅผ ํ™œ์šฉํ•œ CI/CD ๊ตฌ์ถ• - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • GitHub-Actions๋กœ CI/CD๋ฅผ ๊ตฌ์ถ•ํ•  ๋•Œ ๋งค์šฐ ๋งŽ์€ ์‚ฝ์งˆ์„ ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ •๋ฆฌ๋ฅผ ํ†ตํ•ด ๋˜๋Œ์•„๋ณด๊ณ ์ž ํ•จ

์ •๋ฆฌ

  • ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ…์„ ์ž‘์„ฑํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋กœ ๋Œ€์ฒดํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • https://zzang9ha.tistory.com/404

๐Ÿ’ก Kotlin์—์„œ์˜ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์ฆ(@Valid, @field) - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • ๊ธฐ์กด Java & Spring์—์„œ ์‚ฌ์šฉํ•˜๋Š” Validation ๋ฐฉ์‹์ด ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ์ ์šฉ๋˜์ง€ ์•Š์•„์„œ ์›์ธ์„ ํŒŒ์•…ํ•ด๋ณด๊ธฐ ์œ„ํ•ด

์ •๋ฆฌ

  • Spring์—์„œ์˜ Validation์€ ํ•„๋“œ์™€ ๊ฒŒํ„ฐ(getter) ๋ฉ”์†Œ๋“œ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋””์— ๋ถ™์—ฌ๋„ ์˜ˆ์ƒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘์„ ํ•œ๋‹ค.
    • Java์—์„œ Lombok -> @Getter ๋“ฑ์„ ์‚ฌ์šฉ
  • ์ฝ”ํ‹€๋ฆฐ์€ ์ฝ”๋“œ๋“ค์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์—(getter/setter ๋“ฑ) ์–ด๋””์— ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ• ์ง€ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
    • Validation์€ ํ•„๋“œ์˜ ์†์„ฑ์„ ๊ฒ€์ฆํ•˜๊ธฐ ๋•Œ๋ฌธ์— @field: NotEmpty() ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ์ฐธ๊ณ : https://unluckyjung.github.io//kotlin/spring/2022/06/06/kotlin-validation-annotation/

๐Ÿ’ก Spring Security - WebSecurity vs HttpSecurity - ์ง€ํ™˜

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

โ†’ ํ”„๋ก ํŠธ์™€์˜ CORS ์„ค์ •์—์„œ httpSecurity๋Š” ์„ค์ •์ด ์•ˆ๋˜๊ณ , WebSecurity๋Š” ์„ค์ •์ด ๋˜๋Š” ์ด์œ ?

โ†’ ๋น„์Šทํ•œ ๊ฐœ๋…์ด์ง€๋งŒ, ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ฐจ์ด์ ์ด ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•จ.

๊ฐœ๋… & ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•(์„ ํƒ ์ด์œ )

WebSecurity๊ฐ€ HttpSecurity๋ณด๋‹ค ์ƒ์œ„ ๊ฐœ๋…์ด๋‹ค!

โ†’ ๋”ฐ๋ผ์„œ, WebSecurity์—์„œ endpoint๋ฅผ ignoringํ•œ ๊ฒฝ์šฐ์—๋Š” HttpSecurity๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค!

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/health", "/health/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
     http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/health", "/health/**").permitAll()
        .anyRequest().authenticated();
}

WebSecurity

  • Endpoints๋ฅผ ignoringํ•œ ๊ฒฝ์šฐ์—๋Š” Spring Security๋ฅผ ์•„์˜ˆ ๋ฌด์‹œํ•ด๋ฒ„๋ฆฐ๋‹ค.
  • Spring Security Filter Chain์„ ์šฐํšŒํ•˜๊ณ , ๋ณด์•ˆ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š๋Š”๋‹ค!

HttpSecurity

  • ํ•ด๋‹น ๋ฉ”์†Œ๋“œ์—์„œ antMatchers๋ฅผ ํ†ตํ•œ endpoints๋“ค์€ authentication๋งŒ์„ ๋ฌด์‹œํ•œ๋‹ค.
  • Request๋“ค์€ Spring Security Filter Chain์—์„œ ํ—ˆ๊ฐ€๋ฅผ ๋ฐ›์•„์„œ access๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค!

๋”ฐ๋ผ์„œ, HttpSecurity๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ permitAll()์„ ์ง„ํ–‰ํ•œ๋‹ค๋ฉด Spring Security Filter Chain์„ ๊ฑฐ์น˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์šฉ์ด ๋” ๋งŽ์ด ๋“ ๋‹ค.

๋งŒ์•ฝ, endpoint์— ๋Œ€ํ•ด์„œ ์ผ๋ฐ˜์ ์ธ ์ทจ์•ฝ์ ์— ๋Œ€ํ•˜์—ฌ ๋ฐฉ์–ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” HttpSecurity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๋งŒ์•ฝ, authentication ๋ชฉ์ ์„ ๊ฐ€์ง„ ํŠน์ •ํ•œ Request์— ๋Œ€ํ•ด์„œ๋งŒ ๋ฌด์‹œํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ์—๋Š” WebSecurity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค!

โ†’Security์—๋Š” ์ธ์ฆ๋ง๊ณ ๋„ ๋‹ค๋ฅธ ๊ฒƒ์— ๋Œ€ํ•œ filter๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— Security๋ฅผ ํ†ต๊ณผํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” WebSecurity๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , Security์˜ ๋‹ค๋ฅธ filter๋“ค์€ ๋Œ์•„์•ผํ•˜์ง€๋งŒ, authentication์— ๊ด€๋ จํ•ด์„œ ์กฐ์ •์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ์—๋Š” HttpSecurity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ์ข‹์„๋“ฏ!

๋™์‹œ์— WebSecurity์™€ HttpSecurity๋ฅผ ์„ค์ •ํ•œ ๊ฒฝ์šฐ์—๋Š” WebSecurity๊ฐ€ ์ƒ์œ„ ๊ฐœ๋…์ด๊ธฐ ๋•Œ๋ฌธ์— HttpSecurity์— ๋Œ€ํ•œ ์‚ฌํ•ญ๋“ค์€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค!

์ผ๋ฐ˜์ ์œผ๋กœ๋Š” login์„ ํ•  ๋•Œ๋‚˜, public pages์™€ ๊ฐ™์€ Authentication/Authorization์„ ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” endpoint์˜ ๊ฒฝ์šฐ์—๋Š” HttpSecurity๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค!

์ฐธ๊ณ ๋ฌธ์„œ

๋งํฌ


๐Ÿ’ก Swagger2 vs Swagger3 - ์ง€ํ™˜


๐Ÿ’ก Spring Data JPA - CascadeType.REMOVE vs orphanRemoval true - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • JPA์—์„œ ์—ฐ๊ด€ ๊ด€๊ณ„์— ๋Œ€ํ•ด ์ถ”๊ฐ€, ์‚ญ์ œ ๋“ฑ์˜ ์ž‘์—…์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ธ CascadeType, orphanRemoval ๋“ฑ์˜ ์ฐจ์ด์ ์„ ํŒŒ์•…ํ•ด๋ณด๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด

์ •๋ฆฌ

CascadeType.REMOVE

  • CascadeType.REMOVE๋Š” ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋„ ๊ฐ™์ด ์‚ญ์ œ
  • ๋ถ€๋ชจ๊ฐ€ ์ž์‹์˜ ์‚ญ์ œ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌ
  • ํ•˜์ง€๋งŒ ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์˜ ๊ด€๊ณ„๋ฅผ ์ œ๊ฑฐํ•ด๋„ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋Š” ์‚ญ์ œ๋˜์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ์œ ์ง€๋จ

CascadeType ํƒ€์ž…

package javax.persistence;

public enum CascadeType {
    ALL,
    PERSIST,
    MERGE,
    REMOVE,
    REFRESH,
    DETACH;

    private CascadeType() {
    }
}

orphanRemoval = true

  • orphanRemoval = true ์„ค์ • ๋˜ํ•œ ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋„ ์‚ญ์ œ๋จ
  • ํ•˜์ง€๋งŒ ์ด ์˜ต์…˜์€ ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์˜ ๊ด€๊ณ„๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ์ž์‹์€ ๊ณ ์•„(orphan)๋กœ ์ทจ๊ธ‰๋˜์–ด ์‚ญ์ œ๋จ
/* 
Team - Member์ด 1:N์ธ ๊ฒฝ์šฐ
 - 1) ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ
 - 2) ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์˜ ๊ด€๊ณ„๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒฝ์šฐ
*/

// 1)
tempRepository.delete(team);

// 2) CascadeType์™€๋Š” ๋‹ค๋ฅด๊ฒŒ orphanRemoval ์„ค์ •์˜ ๊ฒฝ์šฐ ์•„๋ž˜ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ delete ์ฟผ๋ฆฌ๋ฌธ์ด ์‹คํ–‰์ด ๋จ
team.getMembers().remove(1);

์ฐธ๊ณ 


๐Ÿ’ก RDBMS(PostgreSQL Self References Delete) - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • RDBMS์ธ PostgreSQL์—์„œ Self References ํ•˜๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด ์‚ญ์ œ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌ
  • ํด๋”(Folder) ํ…Œ์ด๋ธ”์€ ๋Œ“๊ธ€/๋Œ€๋Œ“๊ธ€/๋Œ€๋Œ€๋Œ“๊ธ€/... ๋“ฑ๊ณผ ๊ฐ™์ด ๋ฌดํ•œ ์ฐธ์กฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋กœ ๋ณธ์ธ์˜ ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•˜๋Š” ๊ตฌ์กฐ
  • ํ…Œ์ด๋ธ” ๊ตฌ์กฐ image

์ •๋ฆฌ

  • ๋ฌธ์ œ ์ƒํ™ฉ image

image

  • ํ•ด๊ฒฐ
  1. ํ˜„์žฌ FK ์กฐํšŒ image
// Look up the current FK definition 
SELECT pg_get_constraintdef(oid) AS constraint_def
FROM   pg_constraint
WHERE  conrelid = 'public.folder'::regclass  -- assuming public schema
AND    conname = 'fkn0cjh1seljcp0mc4tj1ufh99m';

-- result: "FOREIGN KEY (parent_id) REFERENCES folder(id)"
  1. ํ…Œ์ด๋ธ”์—์„œ DELETE CASCADE ์†์„ฑ ์ถ”๊ฐ€
ALTER TABLE folder
	DROP CONSTRAINT fkn0cjh1seljcp0mc4tj1ufh99m,
	ADD CONSTRAINT fkn0cjh1seljcp0mc4tj1ufh99m
	FOREIGN KEY (parent_id) REFERENCES folder (id) ON DELETE CASCADE;
	
commit;
  1. DELETE CASCADE ์†์„ฑ ํ™•์ธ(pgAdmin4 ๊ธฐ์ค€)
  • ํ…Œ์ด๋ธ” > Constraints > FK ์šฐํด๋ฆญ > Properties ... ํด๋ฆญ
  • Action > On delete : CASCADE ํ™•์ธ image
  1. M:N ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์ธ account_folder ํ…Œ์ด๋ธ”๋„ ์œ„ ๊ณผ์ • ๋™์ผํ•˜๊ฒŒ ์„ค์ •
SELECT pg_get_constraintdef(oid) AS constraint_def
FROM   pg_constraint
WHERE  conrelid = 'public.account_folder'::regclass  -- assuming public schema
AND    conname = 'fkq12fenyrw4agbqxdkoe9j9t0';

-- "FOREIGN KEY (folder_id) REFERENCES folder(id)"

ALTER TABLE account_folder
	DROP CONSTRAINT fkq12fenyrw4agbqxdkoe9j9t0,
	ADD CONSTRAINT fkq12fenyrw4agbqxdkoe9j9t0
	FOREIGN KEY (folder_id) REFERENCES folder (id) ON DELETE CASCADE;

commit;

์ฐธ๊ณ 


๐Ÿ’ก Hibernate - Database Initialization Strategy - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

spring.jpa.generate-ddl vs spring.jpa.hibernate.ddl-auto

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • JPA์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐํ™” ์ „๋žต์— ๋Œ€ํ•ด ๋‘ ์†์„ฑ์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด ์ •ํ™•ํžˆ ํŒŒ์•…ํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ ์ž ์ •๋ฆฌ

์ •๋ฆฌ

  • spring.jpa.generate-ddl
    • true ๋กœ ์„ค์ • ์‹œ ์„œ๋ฒ„ ์‹œ์ž‘ ์‹œ DDL์„ ์ƒ์„ฑํ•˜์—ฌ ์—ฐ๋™๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜
    • default values๋Š” false
    • (boolean) true๋‚˜ false๋งŒ ์„ ํƒ ํ•  ์ˆ˜ ์žˆ์Œ
  • spring.jpa.hibernate.ddl-auto
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐํ™” ์ „๋žต์„ ๋ณด๋‹ค ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•˜๋Š” ์„ค์ • ๊ธฐ๋Šฅ
    • (enum) ํƒ€์ž…์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ default value๋Š” create-drop
      • none: ์•„๋ฌด๋Ÿฐ ์ „๋žต์„ ์ทจํ•˜์ง€ ์•Š์Œ
      • create-drop: SessionFactory๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ๋“œ๋ž ๋ฐ ์ƒ์„ฑ์„ ํ•˜๊ณ , SessionFactory๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ๋“œ๋ž์„ ์ˆ˜ํ–‰
      • create: SessionFactory๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋“œ๋žํ•˜๊ณ , ์ƒ์„ฑ๋œ DDL์„ ์‹คํ–‰
      • update: ๋ณ€๊ฒฝ๋œ ์Šคํ‚ค๋งˆ ์ ์šฉ
      • validate: ๋ณ€๊ฒฝ๋œ ์Šคํ‚ค๋งˆ๊ฐ€ ์กด์žฌํ•˜๋ฉด ์ถœ๋ ฅํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ

์ฐธ๊ณ 


๐Ÿ’ก One table vs Multiple tables - ์ฃผํ˜„

ํŽผ์ณ๋ณด๊ธฐ

์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋œ ๋ฐฐ๊ฒฝ

  • NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์„ค๊ณ„๋„์ค‘ ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์— ํ•„๋“œ ๋ฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์„ ์–ธํ•˜์—ฌ I/O Call์„ ์ค„์ผ์ง€, ํ˜น์€ ํ…Œ์ด๋ธ”์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ณต์žก๋„๋ฅผ ์ค„์ผ์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ
  • ๊ฒฐ๋ก : I/O Call์„ ์ค„์—ฌ ๋Œ€์šฉ๋Ÿ‰ ์ƒํ™ฉ์—์„œ์˜ ๋ถ€ํ•˜๋ฅผ ๊ณ ๋ คํ•˜์—ฌ Embedding์„ ์‚ฌ์šฉ

์ •๋ฆฌ

  • Embedding(ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ๊ด€๋ฆฌ)

    • ์žฅ์ 
      • ๋‹จ์ผ ์ฟผ๋ฆฌ๋กœ ๋ชจ๋“  ๊ด€๋ จ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ
      • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์— join์ด๋‚˜ $lookup๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ๊ตฌํ˜„์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Œ
      • ๋‹จ์ผ ์›์ž์„ฑ์˜ ์ž‘์—…์œผ๋กœ ๊ด€๋ จ ์ •๋ณด๋“ค์„ ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ
    • ๋‹จ์ 
      • ๋งŽ์€ ํ•„๋“œ๊ฐ€ ์—ฐ๊ด€์„ฑ์ด ์—†๋‹ค๋ฉด documents๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋งŽ์€ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒ
      • MongoDB๋Š” 16MB์˜ Document Size ์ œํ•œ์ด ์กด์žฌ -> ๋‹จ์ผ ๋„ํ๋จผํŠธ์— ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ• ๊ฒฝ์šฐ ์ž ์žฌ์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ์ œํ•œ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ
  • Referencing(์ฐธ์กฐ)

    • ์žฅ์ 
      • ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜๋ˆ„๊ธฐ์— ๋ณด๋‹ค ์ž‘์€ ๋„ํ๋จผํŠธ ์‚ฌ์ด์ฆˆ ์œ ์ง€๊ฐ€ ๊ฐ€๋Šฅ
      • ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ 16MB ๋„ํ๋จผํŠธ ์‚ฌ์ด์ฆˆ ์ œํ•œ์— ๋„๋‹ฌํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ์Œ
      • ์ž์ฃผ ์ ‘๊ทผํ•˜์ง€ ์•Š๋Š” ์ •๋ณด๋Š” ์ฟผ๋ฆฌ์— ํ•„์š”ํ•˜์ง€ ์•Š์Œ
      • ๋ฐ์ดํ„ฐ ์ค‘๋ณต ๊ฐ์†Œ
    • ๋‹จ์ 
      • ๊ด€๋ จ ๋„ํ๋จผํŠธ๋ฅผ ์–ป๊ธฐ์œ„ํ•ด ์ตœ์†Œ ๋‘ ๋ฒˆ์˜ ์ฟผ๋ฆฌ ํ˜น์€ $lookup์ด ํ•„์š”ํ•จ -> I/O Call ์ฆ๊ฐ€

์ฐธ๊ณ 


๐Ÿ’ก MongoDB Schema Design - ์ง€ํ™˜

Clone this wiki locally