Daily Study : 2

dazzling:0
|2025. 9. 17. 21:09
반응형

IssuedAt : 25 - 09 - 17 (수)

Daily Study : 2


폴더 별 관심상품 조회 구현

 

- 오늘도 어김 없이 나오는 repository 메서드 심지어 길다 

productRepository.findAllByUserAndProductFolderList_FolderId();

select * from product p 

  left join product_folder pf 

  on  p.id = pf.product_id

  where p.user_id = ? and pf.folder_id = ? 

 

📒 join과 left join의 차이점 ?? 성능 이슈도 있나요? 

결론 부터 말하자면 성능 차이가 있다고 한다. join과 left join은 차이점이 명확하다 

 

(join)은 Inner join 으로 두 테이블에서 조건을 만족하는 데이터가 양쪽 테이블 모두에 존재하는 경우에만 결과를 반환해줍니다. 

예시로 고객과 ,주문이라는 테이블이 있을 시 

SELECT *
FROM 고객 A
JOIN 주문 B ON A.고객ID = B.고객ID;

이 경우에는 주문을 한 적이 있는 고객만 결과에 포함됩니다. 

 

(left join) OUTER JOIN 은 왼쪽 테이블의 모든 데이터를 유지하면서, 오른쪽 테이블에서 매칭되는 데이터가 있으면 가져오고 없으면 NULL로 채워서 가져옵니다. 

위와 똑같은 예시로 

SELECT *
FROM 고객 A
LEFT JOIN 주문 B ON A.고객ID = B.고객ID;

이 경우 주문을 하지 않은 고객도 결과에 포함되며, 주문 관련 데이터는 NULL로 표시됩니다. 

 

🔎 핵심 차이점은 ?? 

데이터 포함 범위 입니다. JOIN은 교집합이고, LEFT JOIN은 왼쪽 테이블 전체를 가져옵니다. 

그리고, NULL 처리인데 LEFT JOIN에서 매칭되지 않는 경우에 데이터는 NULL처리를 합니다. 

결과 행 수에서도 차이가 납니다 고객은 1,000명인데 한번이라도 주문한 사람은 100명밖에 안된다고 했을 때 

JOIN으로 가져오는 행의 수는 100건이지만 LEFT JOIN으로 가져올 시 1,000건입니다. 

 

그래서 성능 차이있습니다. 

예시를 들어서 1,000명 이지만 네이버로 예시를 들어보자면 몇백만, 몇천만 데이터가 차이날 수 있습니다. 

메모리 사용량에서도 LEFT JOIN이 더 많은 결과를 반환하므로 사용량이 증가하며 NULL처리를 위한 추가 메모리도 필요합니다.

 

따라서 고객 전체를 조회 해야하는 경우에는 JOIN을 사용하겠지만, 그렇지 않은 경우에는 JOIN으로 이건 조건에 따라 달라질거같아서 데이터 분포, 인덱스 설정, 쿼리 조건에 따라 달라질거 같다 ? 라는 생각입니다.. 

 

추가로 RIGHT JOIN은 LEFT JOIN과 동일하게 OUTER JOIN이며, LEFT는 왼쪽 테이블 데이터를 다 가져온다 하면 RIGHT은 오른쪽 테이블 전체를 가져오고 데이터가 없는 왼쪽 테이블의 데이터는 NULL처리가 됩니다. 

 

- 제일 어려운 것이 나온거 같다.. 

오름 차순, 내림 차순을 적용하면서 페이지적용을 했을 때 조회하는 쿼리이다 여기서 limit 이라는 쿼리를 처음 보아서 공부를 해야할 거 같다. 

 

📒 Limit과 Offset 

(Limit) 페이징과 관련이 있지만 정확히 보면 페이징을 구현하는 데 사용되는 도구 중 하나라고 한다.. 

정확히는 쿼리 결과에서 반환할 행의 개수를 제한하는 구문이다. 

SELECT * FROM users LIMIT 10;

이 구문은 처음 10개 행만 가져오는 것이다. 

 

페이징을 10개씩 한 페이지로 구현 한다고 했을 때는 

SELECT * FROM products LIMIT 10 OFFSET 0;

SELECT * FROM products LIMIT 10 OFFSET 10;

1페이지에는 10개 행만 가져와서 보겠다는 뜻이고, OFFSET에 대해서 아직 언급하진 않았지만 구문 해석을 먼저 하자면 10개를 건너띄고 11번째부터 10개를 가져오는 것이다. 

 

(Offset) 은 건너띌 행의 개수이다. OFFSET의 숫자가 헷갈릴 수 있고, 나도 헷갈려서 정리를 해두는데 

정확히 "몇 번째부터 시작할지" 가 아니라 , "앞에서 몇 개를 건너띌지"를 의미한다 !! 

 

그래서 프로젝트에서 진행한 어떤 유저가 폴더를 추가하여 관심 상품을 폴더에 추가하고 폴더에 추가 된 관심 상품들을 내림차순, 오름차순을 추가하고 페이징을 적용한 쿼리 같은 경우는 

select *
from product p left join produt_folder pf
  on p.id = pf.product_id
where p.user_id = ?
  and pf.folder_id = ?
order by p.id desc
limit 10,10;

 

 

JPA가 정말 대단하고 좋은 친구라는 것을 다시 한번 느끼게 되면서 JPA를 사용해야 하는 이유를 절실하게 느꼈다. 

 

JPA 숭배하자 

 

라고 하기 보다는 데이터베이스 쿼리에 대해서 깊게 공부해볼 생각이다.. join 과 left join처럼 성능 이슈나는 부분들이 많을 거 같다는 생각이 들었다 쿼리 튜닝 하면서 성능을 올릴 수 있다면 그거 또한 재미있을거 같다. 


배포 준비 하기 

 

- 배포를 단 한번도 안해본 나에게 배포해서 제출 해야 하는 과제가 생겼다.. 

구글링과 AI를 활용하여 배포를 해보려고 하는데 해결 과정을 정리 해야겠다 싶어서 정리 파트에 넣었다...

 

📒 시작은 성공의 반 ..!? 

어제 밤에 AWS 계정 가입을 끝 마친 상태인데 시작은 성공의 반이라고 회원 가입 했으면 시작한거 아닌가 ?? 

 

그리고 Filezilla 설치 까지 하고 나면 설치할 건 더 이상 없다 

이제 AWS 홈페이지에서 설정해야 하는 것만 남았다. 

 

첫 번째로 RDS 구매하고 MySQL 세팅을 진행하였다. 

그 다음엔 AWS EC2 서버를 구매하여 ubuntu 리녹스 os를 설치하고 세팅하였다. 

 

여기서 잠깐 SSH은 중요해서 메모를 해두려고한다. 

SSH(Secure Shell Protocol) 이란 다른 컴퓨터에 접속할 때 사용하는 프로그램이다. 다른 것들 보다 보안이 상대적으로 뛰어나다고 한다. 

접속할 컴퓨터가 22번 포트가 열려있어야 접속 가능하다고 한다. 

 

(EC2 접속하기)

1. sudo chmod 400 받은키페어를끌어다놓기 

2. ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피

 

그리고 우분투 설치한 EC2에서도 java를 설치해주어야 한다. 

1. sudo apt-get update

2. sudo apt-get install openjdk-17-jdk

3. java -version

 

그리고 Filezilla에 우분투 서버를 연결하고 배포할 자르 파일을 넘겨주면 된다. 

그리고 실행 시킬 때는 당연히 자르 파일을 실행시켜주면 된다.. 

java -jar JAR파일명.jar

 

💬 도와주세요 튜터님 !!!!!

아니.. 정상적으로 배포는 했는데 포트번호를 넣지 않으면 접속이 거부당한다 ...

튜터님한테 달려가서 질문했더니 너무 어렵다 ....리버스 프록시가 필요한데 그런 기능을 수행하기 위해서는 nginx서버가 필요하다고 하신다.. 그리고 방화벽으로 포트를 허용하는데 있어서 나중에 MSA 방식으로 배포하게되면 문제가 생길 수 있다고 하신다.. 

웹 개발자는 네트워크에 대한 개념도 빠삭하게 잘 알아야 한다는 것을 다시 느꼈다... 

 

캠프 시작하기 전 재미삼아 홈서버를 구축하려고 할 때 찾아본 자료들 중에서 많이 본 말들을 많이 전해 들었다.. 

포트 허용, 닫기 / 포트포워딩 / SSL / SSH 그러나 첫 배포를 해본 지금도 아직 잘 모르겠다 ..ㅠ 

 

다른 튜터님한테도 달려가서 질문 !!!

우선은 우분투 서버에서 직접 설정할 수 있는 방법을 알려주셨다.. 이건 우분투 버전에 따라서 좀 많이 변경 된 부분인거 같아 따로 위에서 정리를 했다.. 이분은 신이다 신 !!!!!!!!!!!!!!! 아직 정확한 개념은 잘 모르지만 해결이 되었다.. 그래서 이 부분에 대한 건 자료를 찾아보고 클로드랑 열심히 티키타카할 생각이다. 이제는 포트 번호를 넣지 않아도 정상적으로 배포가 된다 후후~~ 

 

📒 배포 이후에는 ?? 

궁금한점이 한두가지가 아니다 

우선 배포 이후에 우분투 서버에서 서버를 실행 시키면서 로컬 환경에서 작업을 실행 시켜보려고 한다. 

그전에 MySQL랑 스프링 부트 연결을 하면서 설정 정보를 application.properties에 저장을 해둔다. 

배포를하면서 MySQL설정정보와 로컬 개발 환경에서의 데이터베이스 설정정보는 완전 다르다. 

그러기에 지금 로컬환경에서 개발을 진행하게 되면 로컬 데이터베이스 환경이 아닌 나도 모르는 어떠한 데이터베이스에 저장이 될 것이다. 

이러한 문제를 해결하는 방법은 뭐가 있을까 ??

 

두 번째 궁금한 점은 내가 자르파일을 우분투 서버에 넘겨주면서 그 시점의 빌드된 파일로 서버가 돌아가고 있을 것이다. 

내가 여기서 기능을 추가하거나 확장한다고 하면 파일을 매번 넘겨주고 우분투에서는 파일을 받고 서버를 중단했다가 다시 실행 해야 하는 불편함이 생겼다. 

 

세 번째는 배포환경에서 사용되는 데이터베이스의 관리이다. 

로컬 개발환경에서는 이제 아무렇지 않게 mysql -u root -p 로 접속하여 간단하게 데이터베이스와 테이블을 CRUD하고 조회 할 수 있는 작업들을 할 수 있었는데 AWS에서 연결된 데이터베이스는 어디서 조회하고 관리할 수 있을까 ? 

 

아직 초보라서 그런지 이 정도 궁금증만 남는거 같다. 

 

- 첫 번째 궁금한 점 application.properties파일 같은 경우는 파일을 여러 개 나누는 것이다. 그러니까 스프링 부트에서는 이런 상황을 해결 할 수 있도록 프로파일을 제공해준다고 하는데.. 환경 별로 파일을 나누어 만드는 것이다. 

application.properties (공통설정)

application-local.properties (로컬 개발용)

application-prod.properties (AWS 배포용)

 

해결 방법은 application.properties에 spring.profiles.active=local로 설정하고 로컬 환경에서 개발을 진행 하면 된다. 

개발이 끝나고 다시 배포하려고 할땐 local 부분을 prod로 바꿔주고 빌드 해서 파일을 보내주면 될 거 같다 ^^!!! 

아직도 불편한점은 매번 이렇게 바꿔줘야 하는 것도 귀찮을 뿐더러, 중복된 코드들이 너무 많다 ..

 

- 두 번째 궁금한 점은 CI/CD를 도입하는 것이다. 

종류가 여러가지 있다는데 GitHub Actions, GitLab CI, Jenkins 등이 있다는데 ..코드를 푸쉬할 때마다 자동으로 빌드 되고 서버 배포 그 다음 재시작까지 해줄 수 있다고 한다. 

어 ? 근데 재시작 한다는 게 결국엔 중단을 한 번 한다는거 아닌가 ? 완전 무중단은 없는건가 ... 

 

세 번째도 더 공부를 해봐야 할 거 같다 ...

 

📒 배포하면서 중요한건 리녹스 명령어도 중요 !

네트워크 관리사2급을 준비하면서 그리고 정처기를 준비하면서 리녹스 명령어도 많이 보기도 했는데 

역시 내가 주로 사용하던 OS가 아니여서 그런지 착착 감기지가 않는다 ..그래서 오늘 배포하면서 좀 중요한 명령어들을 

한번 더 다시 써보자 ! 

 

sudo chmod 400 {키파일} : 관리자 권한으로 해당 파일의 권한을 변경하는 명령어인데 

rwx-rwx-rwx 라고 8진수로 모든 권한을 주게 될 경우 777이 된다. 

r -4 (읽기)

w -2 (쓰기)

x -1 (실행) 

근데 보면 숫자가 한자리만 들어가있다 숫자 자리 수 그대로 해석을 하면

파일소유자 - 그룹 - 기타 사용자 인데 파일소유자만 4라는 것은 

파일 소유자만 해당 파일을 읽을 수 있고 소유자를 제외한 모든 권한은 읽을 권한 조차 안준다 라는 말이다. 

즉 엄청나게 중요한 개인키라던가, 설정 파일등을 보호할 때 사용한다.  

 

ssh -i {키파일} ubuntu@{AWS 에서 받은 IP주소}

ssh는 위에서 설명한 것 처럼 다른 컴퓨터에 접속할 때 사용하는 거라 특별한 것은 없다. 


소셜 로그인

 

- OAuth 란 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단이다. 

HTTP 기반의 보안 프로토콜이며, 대표적으로 구글, 페이스북, 네이버, 카카오가 있다고 한다. 

 

- RestTemplate은 RequiredArgsConstructor로만 구현이 되지 않는다. 

스프링 부트에서 기본적으로 RestTemplate를 바로 빈으로 등록하지 않고, 생성하도록 유도 하고 있다고 한다. 

수동 등록 빈을 사용해야한다. 

RestTemplateBuilder를 파라미터로 받아서 생성을 하는데 중요한건 

생성과정중 setConnectTimeout, setReadTimeout이 버전이 상향 되면서 없어진 것으로 보인다.. 

 

이 부분은 꽤나 복잡해 보인다.. RestTemplate 가 아닌 RestClient로 변경된 거 같은데 우선 학습하는 데 있어서 강사님이랑 버전을 맞추고 진행을 해야겠다.. 참고로 위에 메서드는 스프링 부트 3.2.0 이상 에서는 없어진것으로 확인되었다. 

728x90
반응형

'TIL & STUDY' 카테고리의 다른 글

Daily Study : 6  (1) 2025.09.22
Daily Study : 5  (0) 2025.09.20
Daily Study : 4  (0) 2025.09.19
Daily Study : 3  (3) 2025.09.18
Daily Study : 1  (0) 2025.09.16