본문 바로가기

분류 전체보기116

인덱스 인덱스 인덱스는 데이터베이스 쿼리의 성능을 언급하면서 빼놓을 수 없는 부분이다. MySQL 8.0 버전까지 업그레이드되어 오면서 다른 상용 RDBMS에서 제공하느 많은 기능을 지원하게 됐으며, 기존의 MyISAM 스토리지 엔진에서만 제공하던 전문 검색이나 위치 기반 검색 기능도 모두 InnoDB 스토리지 엔진에서 사용할 수 있게 개선되었다. 아무리 MySQL의 옵티마이저가 발전하고 성능이 개선됐다고 해도 여전히 관리자의 역할은 매우 중요하다. 디스크 읽기 방식 컴퓨터의 CPU나 메모리처럼 전기적 특성을 띤 장치의 성능은 짧은 시간 동안 매우 빠른 속도로 발전했지만 디스크 같은 기계식 장치의 성능은 상당히 제한적으로 발전했다. 여전히 데이터 저장 매체는 컴퓨터에서 가장 느린 부분이기 때문에 데이터베이스나 .. 2023. 11. 6.
트랜잭션과 잠금 트랜잭션과 잠금 트랜잭션 트랜잭션은 꼭 여러 개의 변경 작업을 수행하는 쿼리가 조합됐을 때만 의미 있는 개념은 아니다. 트랜잭션은 하나의 논리적인 작업 셋에 하나의 쿼리가 있든 두 개 이상의 쿼리가 있든 관계없이 논리적인 작업 셋 자체가 100% 적용되거나(COMMIT을 실행했을 때) 아무것도 적용되지 않아야(ROLLBACK 또는 트랜잭션을 ROLLBACK시키는 오류가 발생했을 때)함을 보장해 주는 것이다. MyISAM이나 MEMORY 스토리지 엔진처럼 부분 업데이트 현상이 발생하면 실패한 쿼리로 인해 남은 레코드를 다시 삭제하는 재처리 작업이 필요할 수 있다. 따라서 InnoDB 스토리지 엔진이 지원하는 트랜잭션 기능은 애플리케이션 개발에서 고민해야 할 문제를 줄여주는 아주 필수적인 DBMS의 기능이라.. 2023. 11. 4.
DTO <-> Entity 어디서 변환해야 할까? DTO Entity 어디서 변환해야 할까? 프로젝트를 진행하면서 DTO와 Enity를 어디서 변환하면 좋을지 생각했고, 이 주제는 개발에 있어 다들 많이 하는 고민 중 하나인 것 같다. 데이터베이스 Entity와 클라이언트 또는 API에서 사용하는 DTO(Data Transfer Object) 변환 과정은 데이터 구조 및 비즈니스 로직 차이를 해결하는 데 도움이 된다. 따라서 변환 과정은 개발에 중요한 요소 중 하나라고 생각한다. 그러면 먼저 DTO는 무엇이고, Entity가 무엇인지부터 간단히 살펴보자. Entity Entity는 데이터 모델링에서 레코드 또는 데이터베이스 테이블에서 식별 가능한 하나의 항목을 나타내는 개념이다. Entity는 특정 도메인에서 중요한 정보 단위를 나타내며 데이터베이스에서.. 2023. 11. 3.
InnoDB 스토리지 엔진 아키텍처 InnoDB 스토리지 엔진 아키텍처 InnoDB는 MySQL에서 사용할 수 있는 스토리지 엔진 중 거의 유일하게 레코드 기반의 잠금을 제공하며, 그 때문에 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어나다. InnoDB의 간단한 아키텍처는 위 그림과 같다. 프라이머리 키에 의한 클러스터링 InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장된다. 즉, 프라이머리 키 값의 순서대로 디스크에 저장된다는 뜻이며, 모든 세컨더리 인덱스는 레코드의 주소 대신 프라이머리 키의 값을 논리적인 주소로 사용한다. 프라이머리 키가 클러스터링 인덱스이기 때문에 프라이머리 키를 이용한 레인지 스캔은 상당히 빨리 처리될 수 있다. 결과적으로 쿼리의 실행 계획에 프라이머리 키는 기본적으로 다른.. 2023. 11. 2.
회원가입 동시성 이슈 테스트 - DB Unique 활용하기 회원가입 동시성 이슈 테스트 절대 흔한 일은 아니지만 만약 동시에 두 명의 사용자가 같은 이메일로 회원가입을 하게 되면 어떻게 될까? 이에 대한 궁금증을 해결하기 위해 직접 테스트를 진행해보고자 한다. 회원가입 비즈니스 로직 Service 계층에 위치한 signUp 메서드는 말그대로 회원가입을 진행하는 비즈니스 로직을 담고 있다. 순서는 다음과 같다. validateMemberDto(_): 사용자가 입력한 정보에 대해 유효성을 검사한다. if (isDuplicatedMember(_)) { ... }: 만약 이미 가입한 이메일이 있으면 EmailDuplicationException 예외가 발생한다. signUpMemberDto.toEntity(): DTO -> Entity로 변환한다. setBcryptPa.. 2023. 10. 30.
MySQL 아키텍처 MySQL 아키텍처 MySQL 서버는 사람의 머리 역할을 담당하는 MySQL 엔진과 손발 역할을 담당하는 스토리지 엔진으로 구분할 수 있다. 그리고 스토리지 엔진은 핸들러 API를 만족하면 누구든 스토리지 엔진을 구현해서 MySQL 서버에 추가해서 사용할 수 있다. 즉, MySQL 서버에서 MySQL 엔진은 하나지만 스토리지 엔진은 여러 개를 동시에 사용할 수 있다. MySQL 엔진 MySQL엔진은 클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션 핸들러와 SQL 파서 및 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저가 중심을 이룬다. 또한 MySQL은 표준 SQL(ANSI SQL) 문법을 지원하기 때문에 표준 문법에 따라 작성된 쿼리는 타 DBMS와 호환되어 실행될 수 있다. MySQL 엔진은.. 2023. 10. 24.
MySQL 서버 설정과 사용자 및 권한 MySQL 서버 설정 일반적으로 MySQL 서버는 단 하나의 설정 파일을 사용하는데, 리눅스를 포함한 유닉스 계열에서는 my.cnf라는 이름을 사용하고, 윈도우 계열에서는 my.ini라는 이름을 사용한다. MySQL 8.0 서버의 시스템 변수는 대략 570개 수준이며, 사용하는 플러그인이나 컴포넌트에 따라 시스템 변수의 개수는 더 늘어날 수도 있다. 모든 시스템 변수를 공부해야 하는 것은 아니지만 MySQL 서버를 제대로 사용하려면 시스템 변수에 대한 이해가 상당히 많이 필요하다. 설정 파일 MySQL 서버는 시작될 때만 이 설정 파일을 참조하는데, 이 설정 파일의 경로가 고정되어 있는 것은 아니다. MySQL 서버는 지정된 여러 개의 디렉터리를 순차적으로 탐색하면서 처음 발견된 my.cnf 파일을 사용.. 2023. 10. 21.
빈 후처리기(BeanPostProcessor) 빈 후처리기 스프링에서 빈 후처리기(BeanPostProcessor)는 컨테이너에 의해 생성된 빈 객체의 초기화 과정에서 커스텀 동작을 수행할 수 있도록 해주는 용도로 사용된다. 빈 후처리기는 스프링의 AOP(Aspect-Oriented Programming)와 관련된 작업, 빈 초기와나 소멸 시 추가 작업, 그리고 빈의 커스텀 로직 적용과 같은 다양한 작업을 수행할 때 유용하다. BeanPostProcessor 인터페이스 postProcessBeforeInitialization(Object bean, String beanName): 빈 객체가 초기화되기 전에 호출되는 메서드이다. 이 메서드를 통해 빈 객체를 수정하거나 빈 객체가 초기화되기 전 추가 작업을 수행할 수 있다. postProcessAfter.. 2023. 10. 17.
프록시 팩토리를 통한 AOP 프록시 팩토리 스프리에서 프록시 팩토리는 AOP(Aspect-Oriented Programming)의 핵심 개념 중 하나이다. AOP는 애플리케이션의 핵심 비즈니스 로직 외에도 보안, 로깅, 트랜잭션 관리 등과 같은 다양한 부가적인 관심사를 모듈화하고 분리하는데 사용되는 기술로 이를 통해 코드 중복을 줄이고 코드의 재사용성을 향상시킬 수 있다. 프록시 팩토리는 주로 AOP를 구현하기 위해 사용된다. 스프링은 빈(Bean)을 프록시 객체로 래핑하고, 프록시 객체를 통해 부가적인 관심사를 처리하는 방식으로 AOP를 제공한다. 따라서 클라이언트 코드에 영향을 주지 않으면서 부가적인 동작을 수행할 수 있다. 프록시가 나온 계기 런타임 환경에서 프록시 객체를 동적으로 생성하는 방법에 다음 두 가지 방법이 있다. .. 2023. 10. 16.