전체 글 17

드라이빙 테이블(Driving Table)이란?

드라이빙 테이블(Driving Table)은 SQL쿼리에서 조인(Join)을 수행할 때, 먼저 검색을 시작하는 기준 테이블을 의미한다. 드라이빙 테이블(Driving Table)의 역할은?조인을 수행할 때, 가장 먼저 읽는 테이블드라이빙 테이블의 결과를 기준으로 다른 테이블과 조인쿼리 성능 최적화를 위해 중요SELECT u.id, u.name, o.order_id, o.amountFROM users uJOIN orders o ON u.id = o.user_idWHERE u.name = 'John';users 테이블에서 name = 'John'인 사용자를 찾는다 -> 드라이빙 테이블찾은 id 값을 orders 테이블에서 검색하여 조인--> users 테이블이 먼저 조회되고, 그 결과를 기반으로 orders..

B-Tree 인덱스의 가용성

B-Tree 인덱스의 특징은 왼쪽 값에 기준해서(Left-most) 오른쪽 값이 정렬돼 있다. B-Tree를 사용한 DB의 인덱스는 정렬된 트리 구조를 가지고 있다. 이때, 다중 칼럼(Composite) 인덱스를 사용할 경우, 왼쪽(Left-most) 값이 기준이 된다는 개념이다. CREATE INDEX idx_ab ON table_name (A, B);-> 이렇게 (A, B) 복합(Composite) 인덱스를 만들면, B-Tree 인덱스는 A 열을 먼저 정렬한 후, 같은 A 값을 가진 경우 B를 정렬해 EX)AB값12X13Y14Z21A24B25C32D33E34F  이 개념을 이해하면 인덱스를 제대로 활용할 수 있는 쿼리와 비효율적인 쿼리를 구별할 수 있다. 기본적으로 B-Tree 인덱스의 특성상 아래 ..

JPA 성능 최적화

1. 단순 조회 (기본 키를 이용한 조회)특정 엔티티 하나를 조회할 때, 기본 키(PK)를 사용하면 가장 효율적이다findById()는 기본적으로 1차 캐시(영속성 컨텍스트)를 먼저 조회하기 때문에 성능이 좋음.최적화 방법:EntityManager의 1차 캐시 활용Spring Data JPA의 findById()// 기본 키(PK)로 Task 엔티티 조회 (1차 캐시 활용)Optional task = taskRepository.findById(taskId); -> 불필요한 SQL실행 없이,JPA의 1차 캐시에서 데이터를 가져올 수 있다.  2. 특정 컬럼만 조회할 때 (DTO Projection)엔티티의 전체 필드를 가져오는 것이 아니라, 특정 필드만 필요한 경우엔티티 조회 시 불필요한 데이터 로딩을 방..

데이터베이스 2025.02.25

CSRF(Cross-Site Request Forgery) 공격이란?

CSRF(사이트 간 요청위조)는 공격자가 사용자를 속여서 사용자가 의도하지 않은 요청을 특정 웹 애플리케이션으로 전송하도록 만드는 웹 보안 공격이다.즉, 사용자가 웹사이트에 로그인한 상태에서, 공격자가 사용자 모르게 요청을 보내도록 유도하여 피해를 입히는 방식이다. 1. CSRF 공격의 원리CSRF 공격은 인증된 사용자의 세션을 악용하여 원하지 않는 요청을 서버로 보내는 것이 핵심이다. CSRF 공격 과정사용자 A웹사이트(https://bank.com)에 로그인하고 세션을 유지한 상태.공격자가 악성 웹사이트(B 사이트)를 운영하며, 해당 사이트에 CSRF 공격을 수행할 코드가 포함됨.사용자가 B 사이트를 방문하면, https:/bank.com으로 자동으로 특정 요청을 보내는 스크립트가 실행됨.https:..

@EventListener 어노테이션이란?

@EventListener란?Spring의 ApplicationEvent를 기반으로 동작하며, 특정 이벤트가 발생하면 자동으로 해당 이벤트를 처리하는 메서드를 실행한다.비동기 이벤트 처리(@Async)와 함께 사용가능하여, 비동기 방식으로 이벤트를 처리할 수도 있다.여러 개의 이벤트 타입을 감지할 수 있다. 사용법1. 이벤트 클래스 생성먼저, 이벤트를 정의하는 클래스를 만든다.public class UserCreatedEvent { private final String username; public UserCreatedEvent(String username) { this.username = username; } public String getUsername() { ..

스프링 2025.02.12

@Entity에 대한 @OneToMany 매핑에서 컬렉션의 clear()

@Entity에 대한 @OneToMany 매핑에서 컬렉션의 clear() 메서드를 호출하면 삭제 과정이 효율적이지는 않다. 하이버네이트의 경우 @Entity의 컬렉션 객체의 clear() 메서드를 호출하면 select 쿼리로 대상 엔티티를 로딩하고, 각 개별 엔티티에 대해 delete 쿼리를 실행한다. 즉 컬렉션에 보관 되어 있던 엔티티의 개수가 4개이면 엔티티 목록을 가져오기 위한 한 번의 select 쿼리와 각 엔티티를 삭제하기 위한 네 번의 delete쿼리를 실행한다. 변경 빈도가 낮으면 괜찮지만 빈도가 높으면 전체 서비스 성능에 문제가 될 수 있다. 하이버네이트는 @Embeddable 타입에 대한 컬렉션의 clear() 메서드를 호출하면 컬렉션에 속한 객체를 로딩하지 않고 한 번의 delete 쿼..

스프링 2025.02.05

@Access란?

@Access 어노테이션의 역할JPA에서 엔티티 클래스의 필드를 DB 컬럼과 매핑할 때, 필드 접근 방식과 프로퍼티 접근 방식 두 가지 방법이 있다. @Access 어노테이션을 사용하면 해당 엔티티가 어떤 방식으로 데이터에 접근할 것인지 명시적으로 지정할 수 있다.@Access(AccessType.FIELD) // 필드 접근 방식@Access(AccessType.PROPERTY) // 프로퍼티 접근 방식   1. 필드 접근 방식(AccessType.FIELD) - 객체의 필드(멤버 변수)에 직접 접근하여 값을 설정하고 가져온다. - 필드에 @Column,@Id 등의 JPA 어노테이션을 직접 선언해야 한다. - getter/setter 메서드를 거치지 않고 직접 필드에 접근한다.import jakart..

스프링 2025.02.05

순차 스트림 VS 병렬 스트림

1. 순차 스트림이란?- 데이터 처리가 한 스레드에서 순차적으로 실행된다- 스트림의 요소를 처음부터 끝가지 차례로 처리한다.- 실행 순서가 보장된다.장점- 실행 순서가 명확하게 보장되므로 예측 가능한 결과를 제공- 작은 데이터셋이나 간단한 작업에 적합- 스레드 관리 오버헤드가 없어서 병렬 스트림 보다 가볍다단점- 대용량 데이터를 처리하거나 복잡한 연산이 필요한 경우 성능이 제한된다. 2. 병렬 스트림이란?- 데이터를 여러 스레드로 분할하여 병렬로 처리- 내부적으로 ForkJoinPool을 사용하여 작업을 병렬 처리한다.- 실행 순서를 보장하지 않으며, 결과의 순서를 중요하게 생각하지 않을 때 적합하다.장점- 대용량 데이터를 처리할 때 처리 속도를 크게 향상할 수 있다.- CPU 코어를 효율적으로 활용하여..

자바 2025.01.21

Sharding

샤딩(Sharding)이란?-> 데이터를 여러 데이터베이스에 분산하여 저장하는 기술  샤드(Shard)란?-> 샤딩된 각각의 데이터 단위 샤딩에는 다양한 방법이 존재한다.ex) 수직 샤딩, 수평 샤딩 수직 샤딩(Vertical Sharding): 데이터를 수직으로 분할하는 방식(컬럼 단위) 수평 샤딩(Horizontal Sharding): 데이터를 수평으로 분할하는 방식   범위 기반 샤딩(Range-based Sharding): 데이터를 Shard Key의 범위에 따라 분할하는 기법ex) 좌측 샤드 article_id = 1~5000, 우측 샤드 article_id = 5001~10000범위 데이터 조회 유리-> article_ id = 100부터 30개 조회한다면 좌측 샤드에서 찾을 수 있음데이터 쏠..

데이터베이스 2025.01.08

람다 캡처링(Capturing lamda)

람다 표현식에서는 익명 함수가 하는 것처럼 자유 변수를 활용할 수 있다. 이를 람다 캡처링이라고 한다. int portNumber = 8080;Runnable r = () -> System.out.println(portNumber);이 코드는 컴파일이 된다. 하지만 자유 변수에도 제약이 있다. 람다는 인스턴스 변수와 정적 변수를 자유롭게 자신의 바디에서 참조할 수 있도록 할 수 있다.하지만 그러기 위해서는 지역 변수는 명시적으로 final로 선언되어 있어야 하거나 실직적으로 final로 선언된 변수와 똑같이 사용되어야 한다.int portNumber = 8080;Runnable r = () -> System.out.println(portNumber);portNumber = 3307;이 코드는 컴파일 에러..

자바 2024.12.31