본문 바로가기

전체보기

(240)
AbstractAggregateRoot의 동작 원리(with @PostUpdate로 맞이한 버그) AbstractAggregationRoot 동작 원리 AbstractAggregateRoot는 DDD(Domain Driven Design)를 구현하기 편리하게 해 주는, 정확히는 도메인 이벤트를 등록하고 가져오기 편리하게 해주는 클래스 정도로 이해하고 있다. (클래스 이름과 다르게 추상 클래스가 아니다.) AbstractAggregateRoot와 같이 무언가에서 편의 기능을 제공해줄 때는 항상 트레이드 오프(trade-off)가 있다. 즉, 편의 기능을 사용하는 만큼 개발 생산성이 올라가지만, 동작 원리를 모른 채 사용하다보면 훗날에 대가를 치르게 되어있다. 이 포스트는 그 대가를 치르고 남기는 포스트다. AbstractAggregateRoot 코드 분석 public class AbstractAggre..
JPA @OneToOne은 FetchType.LAZY가 안 먹힐 수 있다? JPA에서 @OneToOne 연관관계일 때 지연 로딩이 안 될 수 있다? 이제는 JPA가 상당히 많이 쓰이고 있기도 하고 유명한 모 강의도 있어서 많은 사람들이 잘 알고 쓰고 있긴하다. 그러나 실제 경험해본 것과 학습을 통해서 아는 것에는 차이가 있다. 실무 중에 @OneToOne 연관 관계가 설정되어 있는 엔티티에 Querydsl을 이용하여 통계 데이터를 조회해보면서 Lazy로 동작하지 않는 것을 확인하며 블로그로 남겨야겠다고 생각했다. (🔥 이 포스트의 독자의 기준은 JPA 기초 정도는 아는 사람이라고 판단하고 작성했다!) 대부분의 JPA를 학습한 사람들이 알고 있듯, ~ToOne(@OneToOne, @ManyToOne) 연관 관계일 때는 Default로 FetchType.EAGER로 동작하고 있다...
2021년 회고🚩-준비되지 않은 중니어(?)의 미래 두 번째 회고 2021년에 2020년에 대한 회고를 첫 번째로 해보고 이번이 두 번째다. 이번에는 과거에 어떤 생각을 했었는지 회고 내용이 있으니 그것을 읽어보면서 어떤 것을 이뤘는지 이루지 못했는지, 이루지 못했다면 왜 그렇게 되었는지 생각해볼 수 있을 것 같다. (항상 뭐 한 것도 없는데 시간이 흘러 다음 해가 되었네? 하는 생각이 든다.) 2021년 목표와 회고 📘 보고 싶은 책 보기 자바 ORM 표준 JPA 프로그래밍, 친절한 SQL 튜닝, 오라클 성능 고도화 원리와 해법, 새로 쓴 대용량 데이터베이스 솔루션 (총 4권) 실패. 자바 ORM 표준 JPA 프로그래밍만 읽었고 나머지 3권은 구매조차 하지 못했다. 2022년에는 주니어를 넘어 중니어(?)는 되는데 기본에 충실하기 위해서 데이터베이스 특..
MySQL 쿼리 작성 및 최적화 쿼리 작성에 필요한 기초 지식 MySQL은 영어 대소문자를 구분한다. 이유는 통상적으로 DB 내용이 디렉토리나 파일로 관리되는데 윈도우OS에선 디렉토리나 파일의 대소문자를 구분하지 않지만, 유닉스 계열에서는 대소문자를 구분하기 때문이다. 설정 파일에서 모두 소문자로만 저장되도록 할 수 있긴하다. 리터럴 표기법 문자열은 항상 홑 따옴표(')로 감싼다. 예약어와 충돌이 예상되는 경우 백 틱(`)으로 감싼다. (사실 예약어는 되도록 다른 곳에 사용하지 않는 게 정석이다.) 문자열과 상수 비교 시 숫자를 우선으로 하여 문자를 숫자로 변환한다. 숫자 값을 상수로 SQL에서 사용할 때는 DBMS가 자동으로 타입에 맞게 변경해준다. SELECT * FROM tab_test WHERE number_column='100..
MySQL의 동작 방식 MySQL의 주요 동작 방식 MySQL이 일련의 쿼리를 수행할 때 동작하는 방식에 대해서 이해해본다. 세세한 부분까지 다 파악한다기보다 일반적인 쿼리 사용자 레벨에서 주의를 기울여야 하는 부분만 알아본다. 풀 스캔 인덱스를 타지 않고 스토리지 엔진이 처음부터 끝까지 전부 다 읽어서 요청된 작업을 처리하는 방법이다. MySQL은 언제 풀 테이블 스캔 방식을 실행계획으로 선택하는가? 테이블의 레코드 건 수가 너무 적어서 인덱스를 통해 읽는 것 보다 풀 테이블 스캔이 빠를 것으로 예상되는 경우 WHERE 절이나 ON 절에 인덱스를 이용할 수 있는 적절한 조건이 없는 경우 인덱스 레인지 스캔을 사용할 수 있는 경우더라도 조건에 일치하는 레코드 건수가 너무 많을 것으로 예상되는 경우 ORDER BY 처리(Usin..
MySQL LIMIT 최적화(feat. 구글이 검색결과를 최대 1,000건만 제공하는 이유) 제가 말하는 것이 사실도, 정답도 아닐 수 있으니 비판적으로 읽어주시면 감사하겠습니다. MySQL LIMIT 최적화하는 방법 MySQL에서 페이징 처리를 위하여 LIMIT 키워드를 제공한다. 오라클에서는 페이징 처리를 위해 rownum 으로 레코드에 번호를 부여하고 WHERE 절에 조건 걸어서 일일이 페이징 처리하던 것에 비해 훨씬 편리하여 자주 사용된다. 이러한 페이징 처리 방법을 오프셋(offset) 페이징이라 한다. MySQL에서 제공하는 LIMIT 즉, 오프셋 페이징에는 치명적인 단점이 있다. 그것은 바로 오프셋 만큼 레코드를 읽어온 후에 필요한 레코드 수를 제외한 "나머지는 버리는 방식"으로 동작하는 것이다. 예를 들어 쿼리가 SELECT ... LIMIT 5000000, 10 처럼 LIMIT ..
MySQL 실행 계획(좋은 쿼리는 못 만들어도 뭐같은 쿼리는 만들지 말아야지) DB의 꽃 옵티마이저의 실행 계획 수립 RDBMS에서 가장 복잡하면서 가장 중요한 것은 옵티마이저(Optimizer)가 쿼리를 어떻게 실행할지 실행 계획을 결정하는 부분이다. 똑같은 쿼리라 할지라도 다양한 방법과 순서로 실행 될 수 있다. 어떤 실행 계획이 좋고 어떤 실행 계획이 안 좋은지 판단하는 건 온전히 옵티마이저의 몫이지만 개발자 역시도 어떤 실행 계획으로 수행되어야 좋은지를 알아야 최적의 실행 계획을 사용할 수 있도록 옵티마이저에게 힌트를 줄 수 있기 때문에 중요하고 반드시 학습해야하는 부분이다. 사전 지식 실행 계획에 대해 자세히 살펴보기 전에 아래의 사전 지식이 있어야 한다. 쿼리 실행 절차 SQL을 SQL 파서가 파싱하여 파서 트리(parser tree)를 만든다. 파서 트리를 기준으로 옵..
MySQL 인덱스 구조와 원리의 이해 인덱스란? 어떤 문제를 해결하기 위한 기술인가 관계형 데이터베이스는 기본적으로 데이터 영속화라는 목적이 있는 기술이다. 쉽게 말하면 어떤 애플리케이션에 필요한 데이터를 유지(저장)하는데 목적이 있다. 그러나 단순히 저장만 하는 게 아니라 저장된 데이터를 가지고 서비스를 해야 한다. 그렇다 보니 수많은 데이터 중에서 특정 조건을 만족하는 데이터를 조회하는데 일일이 검사를 하게 되면 조회 시간이 점차 증가하게 되기 마련이다. (이것은 성능 저하이자 곧 서비스 품질 저하다.) 데이터를 하나하나 전부다 조건을 검사하게 되면 검색 성능이 매우 떨어지는 문제가 발생하는데 이 문제를 해결하기 위한 기술이 바로 인덱스다. 어떻게 해결하는지 쉽게 설명하면, 일반적으로 책 뒤에 "색인"처럼 어느 페이지에 어떤 단어가 있는..