<feed xmlns="http://www.w3.org/2005/Atom"> <id>https://yj901010.github.io/</id><title>YJ.DEV</title><subtitle>Java/Spring 기반 백엔드 개발, 데이터베이스, 아키텍처, 인프라와 프로젝트 트러블슈팅을 기록하는 YJ.DEV 기술 블로그입니다.</subtitle> <updated>2026-10-02T16:33:43+09:00</updated> <author> <name>YJ</name> <uri>https://yj901010.github.io/</uri> </author><link rel="self" type="application/atom+xml" href="https://yj901010.github.io/feed.xml"/><link rel="alternate" type="text/html" hreflang="ko-KR" href="https://yj901010.github.io/"/> <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator> <rights> © 2026 YJ </rights> <icon>/assets/img/favicons/favicon.ico</icon> <logo>/assets/img/favicons/favicon-96x96.png</logo> <entry><title>800GB 테이블 조회 12초에서 0.4초가 된 이유?</title><link href="https://yj901010.github.io/posts/800gb-index-performance/" rel="alternate" type="text/html" title="800GB 테이블 조회 12초에서 0.4초가 된 이유?" /><published>2026-09-11T15:37:21+09:00</published> <updated>2026-10-01T00:00:00+09:00</updated> <id>https://yj901010.github.io/posts/800gb-index-performance/</id> <content type="text/html" src="https://yj901010.github.io/posts/800gb-index-performance/" /> <author> <name>YJ</name> </author> <category term="Database" /> <category term="Performance" /> <summary>최근 회사에서 업무를 하던 중, 원본 DB에서 DT로 데이터를 가져오지 못해 원본 DB를 직접 조회해야 하는 상황이 발생했다. 그동안 우리가 주로 사용하던 RDB 테이블은 데이터가 많아봐야 수십 GB 수준이었다. 물론 이 정도 크기의 테이블도 조회가 오래 걸리는 경우는 있었지만, 800GB 정도 되는 테이블을 직접 조회해본 것은 이번이 처음이었다. 이전까지는 DT로 가져온 테이블을 대상으로 작업하는 경우가 많았고, 그 테이블에는 별도의 인덱스를 걸지 않은 상태에서 조회하는 경우도 많았다. 그러다 보니 인덱스가 중요하다는 것은 알고 있었지만, 실제로 인덱스 하나 때문에 조회 성능이 얼마나 크게 달라질 수 있는지 체감해본 적은 없었다. 그런데 이번에 인덱스의 중요성을 제대로 경험했다. 처음 작...</summary> </entry> <entry><title>Spring 백엔드에서 API 요청 하나는 어떻게 처리될까?</title><link href="https://yj901010.github.io/posts/spring-api-request-flow/" rel="alternate" type="text/html" title="Spring 백엔드에서 API 요청 하나는 어떻게 처리될까?" /><published>2026-09-03T09:50:05+09:00</published> <updated>2026-10-01T00:00:00+09:00</updated> <id>https://yj901010.github.io/posts/spring-api-request-flow/</id> <content type="text/html" src="https://yj901010.github.io/posts/spring-api-request-flow/" /> <author> <name>YJ</name> </author> <category term="Backend" /> <category term="Spring" /> <summary>백엔드를 처음 공부할 때는 API 하나를 굉장히 단순하게 생각했다. 프론트에서 API를 호출하면 Controller가 요청을 받고, Service를 호출한 다음 DB에 저장하고 응답을 돌려주는 정도라고 생각했다. 큰 틀에서는 맞는 말이다. 그런데 실제 코드를 작성하다 보면 그 사이에 생각보다 많은 과정이 있다는 걸 알게 된다. 예를 들어 주문 하나를 생성하는 API만 만들어도 다음과 같은 것들을 고민해야 한다. 요청으로 어떤 값을 받을지 잘못된 값이 들어오면 어디에서 막을지 사용자가 실제로 존재하는지 상품이 존재하는지 재고가 충분한지 주문과 재고 변경을 하나의 작업으로 묶을지 실패했을 때 어떤 상태 코드를 내려줄지 응답에는 어떤 값을 보여줄지 이번 글에서는 아...</summary> </entry> <entry><title>회사 DB 한 테이블 전체를 Update 해버렸다?</title><link href="https://yj901010.github.io/posts/database-full-update-retrospective/" rel="alternate" type="text/html" title="회사 DB 한 테이블 전체를 Update 해버렸다?" /><published>2026-08-26T18:18:03+09:00</published> <updated>2026-10-01T00:00:00+09:00</updated> <id>https://yj901010.github.io/posts/database-full-update-retrospective/</id> <content type="text/html" src="https://yj901010.github.io/posts/database-full-update-retrospective/" /> <author> <name>YJ</name> </author> <category term="Database" /> <category term="Retrospective" /> <summary>개발하다 보면 “이건 금방 끝나겠는데?” 싶은 작업이 있다. 이번 일이 딱 그랬다. PostgreSQL의 어떤 테이블에 원래 NULL이어야 할 값들이 NaN으로 들어가 있었다. PostgreSQL은 숫자 타입에서 NaN을 지원하니까 DB 입장에서는 이상한 값은 아니었지만, 우리 쪽에서는 이걸 NULL로 정리해야 했다. 그래서 여러 컬럼에 NULLIF를 적용하기 시작했다. UPDATE target_table SET column_a = NULLIF(column_a, 'NaN'), column_b = NULLIF(column_b, 'NaN'), column_c = NULLIF(column_c, 'NaN'); 문제는 컬럼이 많았다는 것. 비슷한 구문을 계속 복붙하다가 결국...</summary> </entry> <entry><title>비즈니스 로직은 Service에만 넣으면 될까?</title><link href="https://yj901010.github.io/posts/business-logic-service-domain/" rel="alternate" type="text/html" title="비즈니스 로직은 Service에만 넣으면 될까?" /><published>2026-08-21T14:38:11+09:00</published> <updated>2026-10-01T00:00:00+09:00</updated> <id>https://yj901010.github.io/posts/business-logic-service-domain/</id> <content type="text/html" src="https://yj901010.github.io/posts/business-logic-service-domain/" /> <author> <name>YJ</name> </author> <category term="Backend" /> <category term="Design" /> <summary>처음에는 “비즈니스 로직은 Service에 둔다”라고 이해해도 괜찮다. 하지만 기능이 복잡해질수록 모든 로직을 Service에 몰아넣기보다는 역할에 따라 나누는 것이 좋다. Controller → HTTP 요청과 응답을 처리한다. Service → 하나의 기능이 실행되는 전체 흐름을 조율한다. Domain 객체 → 자기 상태와 관련된 규칙과 행동을 담당한다. Repository → 데이터를 조회하고 저장한다. 쉽게 말하면, Service는 일을 어떤 순서로 진행할지 알고, Domain 객체는 자기 상태에서 무엇을 할 수 있는지 안다. 처음에는 왜 Service에 비즈니스 로직을 넣을까? Spring을 처음 배우면 보통 이런 구조부터 접하게 된다. Controller ...</summary> </entry> <entry><title>의존성 방향은 왜 중요할까?</title><link href="https://yj901010.github.io/posts/dependency-direction/" rel="alternate" type="text/html" title="의존성 방향은 왜 중요할까?" /><published>2026-08-21T11:36:17+09:00</published> <updated>2026-10-01T00:00:00+09:00</updated> <id>https://yj901010.github.io/posts/dependency-direction/</id> <content type="text/html" src="https://yj901010.github.io/posts/dependency-direction/" /> <author> <name>YJ</name> </author> <category term="Architecture" /> <category term="Design" /> <summary>Spring으로 백엔드 개발을 시작하면 거의 항상 이런 구조를 만나게 된다. Controller → Service → Repository 처음에는 그냥 이렇게 외우기도 한다. Controller에서 Service를 호출하고, Service에서 Repository를 호출하면 된다. 그런데 개발하다 보면 조금씩 궁금해진다. 왜 꼭 이 방향이어야 하지? Repository가 Service를 호출하면 안 되나? Service에서 ResponseEntity를 반환하면 왜 안 좋다고 하지? 인터페이스는 왜 만드는 거지? 이 질문들은 결국 하나의 주제로 연결된다. 의존성 방향이다. 한 줄로 먼저 이해하기 의존성 방향을 신경 쓰는 이유는 간단하다. 코드 하나가 바뀌었을 때 ...</summary> </entry> </feed>
