-
Notifications
You must be signed in to change notification settings - Fork 0
Trouble Shooting
- ์ ๋ฆฌ๋ฅผ ํ๊ฒ ๋ ๋ฐฐ๊ฒฝ
- ๊ฐ๋ & ํด๊ฒฐ ๋ฐฉ๋ฒ(์ ํํ ์ด์ )
- ์ฐธ๊ณ ๋ฌธ์
ํผ์ณ๋ณด๊ธฐ
โ ๋น์ทํ ์ญํ ์ ํ๋ ๊ฒ ๊ฐ์ ๋ ๊ธฐ๋ฅ์ด ๋ฌด์จ ์ฐจ์ด๊ฐ ์๋์ง?
โ ์ฑ๋ฅ ์์ ์ฐจ์ด๊ฐ ์กด์ฌํ๋์ง์ ๋ํ ๊ถ๊ธ์ฆ
ํ์ค๋ก ์์ฝํด๋ณด๋ฉด, ๋ ์ ์์ผ๋ฉด 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์ผ๋ก ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค.
IN ์ฐ์ฐ์ ์์ ์๋ ์๋ธ ์ฟผ๋ฆฌ
โ ๊ทธ๋ฅ join์ผ๋ก ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค.
NOT IN ์ฐ์ฐ์ ์์ ์๋ ์๋ธ ์ฟผ๋ฆฌ
โ NOT ๋์ NULL์ ์ฌ์ฉํจ์ผ๋ก์จ join์ผ๋ก ๋ณ๊ฒฝํ์, JOINํ๋ ์์น๋ฅผ ์ ์ง์ ํด์ JOINํด์ฃผ์
EXISTS, NOT EXISTS ์ฐ์ฐ์ ์์ ์๊ด๊ด๊ณ ์๋ธ ์ฟผ๋ฆฌ
โ NOT ๋์ NULL์ ์ฌ์ฉํจ์ผ๋ก์จ join์ผ๋ก ๋ณ๊ฒฝํ์, JOINํ๋ ์์น๋ฅผ ์ ์ง์ ํด์ JOINํด์ฃผ์
GROUP BY๋ฅผ ์ฌ์ฉํ ์๋ธ ์ฟผ๋ฆฌ๊ฐ FROM ์ ์ ์์ ๋
์ง๊ณ๋ ๊ฐ์ ๋ฐํํ๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ WHERE ์ ์ ์์ ๋
์๋ธ ์ฟผ๋ฆฌ๊ฐ ALL ์ฐ์ฐ์์ ์์ ๋
- ์ผ์ชฝ: join, ์ค๋ฅธ์ชฝ: Subquery
https://kimsyoung.tistory.com/entry/SUBQUERY-์-JOIN-์-์ฐจ์ด-ไธ
https://kimsyoung.tistory.com/entry/SUBQUERY-์-JOIN-์-์ฐจ์ด-ไธ
https://kimsyoung.tistory.com/entry/์๋ธ-์ฟผ๋ฆฌ์-์ข ๋ฅ์๋-๋ฌด์์ด-์์๊น
ํผ์ณ๋ณด๊ธฐ
- GitHub-Actions๋ก CI/CD๋ฅผ ๊ตฌ์ถํ ๋ ๋งค์ฐ ๋ง์ ์ฝ์ง์ ํ์๊ธฐ ๋๋ฌธ์ ์ ๋ฆฌ๋ฅผ ํตํด ๋๋์๋ณด๊ณ ์ ํจ
- ๋ธ๋ก๊ทธ ํฌ์คํ ์ ์์ฑํ์๊ธฐ ๋๋ฌธ์ ์ด๋ก ๋์ฒดํ๊ฒ ์ต๋๋ค.
- https://zzang9ha.tistory.com/404
ํผ์ณ๋ณด๊ธฐ
- ๊ธฐ์กด 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/
ํผ์ณ๋ณด๊ธฐ
โ ํ๋ก ํธ์์ 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๋ฅผ ์ฌ์ฉํ๋ค!
ํผ์ณ๋ณด๊ธฐ
- JPA์์ ์ฐ๊ด ๊ด๊ณ์ ๋ํด ์ถ๊ฐ, ์ญ์ ๋ฑ์ ์์ ์ ํ ๋ ์ฌ์ฉํ ์ ์๋ ์ต์ ์ธ CascadeType, orphanRemoval ๋ฑ์ ์ฐจ์ด์ ์ ํ์ ํด๋ณด๊ณ ์ ํํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด
-
CascadeType.REMOVE
๋ ๋ถ๋ชจ ์ํฐํฐ๊ฐ ์ญ์ ๋๋ฉด ์์ ์ํฐํฐ๋ ๊ฐ์ด ์ญ์ - ๋ถ๋ชจ๊ฐ ์์์ ์ญ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌ
- ํ์ง๋ง ๋ถ๋ชจ ์ํฐํฐ๊ฐ ์์ ์ํฐํฐ์ ๊ด๊ณ๋ฅผ ์ ๊ฑฐํด๋ ์์ ์ํฐํฐ๋ ์ญ์ ๋์ง ์๊ณ ๊ทธ๋๋ก ์ ์ง๋จ
package javax.persistence;
public enum CascadeType {
ALL,
PERSIST,
MERGE,
REMOVE,
REFRESH,
DETACH;
private CascadeType() {
}
}
-
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 ํ๊ณ ์๋ ํ ์ด๋ธ์ ๋ํด ์ญ์ ๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ ๋ฆฌ
- ํด๋(Folder) ํ ์ด๋ธ์ ๋๊ธ/๋๋๊ธ/๋๋๋๊ธ/... ๋ฑ๊ณผ ๊ฐ์ด ๋ฌดํ ์ฐธ์กฐ๋ฅผ ํ ์ ์๋ ๊ตฌ์กฐ๋ก ๋ณธ์ธ์ ํ ์ด๋ธ์ ์ฐธ์กฐํ๋ ๊ตฌ์กฐ
- ํ ์ด๋ธ ๊ตฌ์กฐ
- ๋ฌธ์ ์ํฉ
- ํด๊ฒฐ
- ํ์ฌ FK ์กฐํ
// 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)"
- ํ ์ด๋ธ์์ DELETE CASCADE ์์ฑ ์ถ๊ฐ
ALTER TABLE folder
DROP CONSTRAINT fkn0cjh1seljcp0mc4tj1ufh99m,
ADD CONSTRAINT fkn0cjh1seljcp0mc4tj1ufh99m
FOREIGN KEY (parent_id) REFERENCES folder (id) ON DELETE CASCADE;
commit;
- DELETE CASCADE ์์ฑ ํ์ธ(pgAdmin4 ๊ธฐ์ค)
- ํ ์ด๋ธ > Constraints > FK ์ฐํด๋ฆญ > Properties ... ํด๋ฆญ
- Action > On delete : CASCADE ํ์ธ
- 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;
ํผ์ณ๋ณด๊ธฐ
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
: ๋ณ๊ฒฝ๋ ์คํค๋ง๊ฐ ์กด์ฌํ๋ฉด ์ถ๋ ฅํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ
-
ํผ์ณ๋ณด๊ธฐ
- NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ์ค๊ณ๋์ค ํ๋์ ํ ์ด๋ธ์ ํ๋ ๋ฐ ๋ฆฌ์คํธ๋ฅผ ์ ์ธํ์ฌ I/O Call์ ์ค์ผ์ง, ํน์ ํ ์ด๋ธ์ ๋ถ๋ฆฌํ์ฌ ๋ณต์ก๋๋ฅผ ์ค์ผ์ง์ ๋ํ ๊ณ ๋ฏผ
- ๊ฒฐ๋ก : I/O Call์ ์ค์ฌ ๋์ฉ๋ ์ํฉ์์์ ๋ถํ๋ฅผ ๊ณ ๋ คํ์ฌ Embedding์ ์ฌ์ฉ
-
Embedding(ํ๋์ ํ ์ด๋ธ์์ ๋ชจ๋ ๊ฒ์ ๊ด๋ฆฌ)
- ์ฅ์
- ๋จ์ผ ์ฟผ๋ฆฌ๋ก ๋ชจ๋ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ป์ ์ ์์
- ์ดํ๋ฆฌ์ผ์ด์ ์ฝ๋์ join์ด๋ $lookup๊ณผ ๊ฐ์ ์ฝ๋ ๊ตฌํ์ ํผํ ์ ์์
- ๋จ์ผ ์์์ฑ์ ์์ ์ผ๋ก ๊ด๋ จ ์ ๋ณด๋ค์ ์ ๋ฐ์ดํธ ๊ฐ๋ฅ
- ๋จ์
- ๋ง์ ํ๋๊ฐ ์ฐ๊ด์ฑ์ด ์๋ค๋ฉด documents๊ฐ ์ปค์ง์๋ก ๋ง์ ์ค๋ฒํค๋๊ฐ ๋ฐ์
- MongoDB๋ 16MB์ Document Size ์ ํ์ด ์กด์ฌ -> ๋จ์ผ ๋ํ๋จผํธ์ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๊ฒฝ์ฐ ์ ์ฌ์ ์ผ๋ก ์ด๋ฌํ ์ ํ์ ๋๋ฌํ ์ ์์
- ์ฅ์
-
Referencing(์ฐธ์กฐ)
- ์ฅ์
- ๋ฐ์ดํฐ๋ฅผ ๋๋๊ธฐ์ ๋ณด๋ค ์์ ๋ํ๋จผํธ ์ฌ์ด์ฆ ์ ์ง๊ฐ ๊ฐ๋ฅ
- ์์์ ์ธ๊ธํ 16MB ๋ํ๋จผํธ ์ฌ์ด์ฆ ์ ํ์ ๋๋ฌํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ์
- ์์ฃผ ์ ๊ทผํ์ง ์๋ ์ ๋ณด๋ ์ฟผ๋ฆฌ์ ํ์ํ์ง ์์
- ๋ฐ์ดํฐ ์ค๋ณต ๊ฐ์
- ๋จ์
- ๊ด๋ จ ๋ํ๋จผํธ๋ฅผ ์ป๊ธฐ์ํด ์ต์ ๋ ๋ฒ์ ์ฟผ๋ฆฌ ํน์ $lookup์ด ํ์ํจ -> I/O Call ์ฆ๊ฐ
- ์ฅ์