목록Backend (22)
신비한 개발사전
WHERE 절은 SELECT 전에 처리되기 때문에 WHERE 절에서 alias를 사용할 수 없다. SQL 질의 처리 순서에 대해 학습하면서 알게 된 것 중에 가장 의아했던 문장이다. 문장의 내용과 반대되게 내가 직접 WHERE 절에서 alias를 쓴 기억이 있기 때문이다. 확인하기 위해 SQLite에서 아래 쿼리문을 실행해봤다.SELECT price AS pFROM "availabilities"WHERE p > 100LIMIT 10; WHERE 절에서 alias인 "p"로 조건을 붙여도 오류 없이 잘 동작하는 것을 볼 수 있다: 결론부터 말하자면, 이건 SQLite이 예외적으로 WHERE 절에서도 alias 사용을 허용하기 때문이다. 같은 맥락으로 MySQL에서도 동일하게 WHERE 절에 alias를 사..
스토리지 엔진(또는 데이터베이스 엔진)은 데이터의 직접적인 읽고 쓰기 작업을 수행하는 데이터베이스 관리 시스템(DBMS)의 컴포넌트다. 디스크 I/O 외에도 데이터를 어떤 자료구조로 저장할지, 혹은 데이터 접근 요청이 동시다발적으로 들어올 때 어떻게 제어할지 등, 논리적으로 데이터를 다루는 부분까지도 스토리지 엔진의 역할이다. 1960년대에 데이터를 자료구조에 저장하기 시작한 이후로 다양한 스토리지 엔진이 개발되었다. 한번쯤 들어봤을 법한 MySQL의 InnoDB나 MongoDB의 WiredTiger 엔진 외에도 RocksDB, MEMORY, LevelDB 등의 엔진들이 시장에서 활약하고 있다. 필요에 따라 자체 스토리지 엔진을 개발해서 쓰는 회사도 있는데, 이렇게까지 다양한 스토리지 엔진이 필요한 이유..
현재 진행하고 있는 팀 프로젝트는 입력 받은 지하철 역들의 중간 지점에 위치한 역을 찾아주는 서비스다. 중간 역이라고 하면 각 시작점에서 비슷한 시간이 소요되는 역을 말하는데, 우리는 이동시간을 계산하기 위해 먼저 물리적인 중간 지점을 파악하고, 해당 지점 인근의 역을 찾아야겠다고 판단했다. 일단 도착지가 있어야 이동시간을 계산할 수 있기 때문이다. PostgreSQL DB의 PostGIS 플러그인은 지리 공간 데이터(geospatial data)와 관련된 다양한 기능을 지원하는데, 그 중 하나가 특정 x 좌표의 n 반경 내 모든 위도와 경도를 쿼리해주는 기능이다. 우리는 PostGIS를 활용해 중간 지점 경위도의 n 반경 안에 있는 역들을 DB에서 조회하기로 했다. PostGIS 설치하기PostgreS..
문제 의식데이터 수정 작업을 수행할 때, 한 트랜잭션 단위 안에서 작업이 이루어지도록 메서드에 @Transactional 애노테이션을 붙인다. 중간에 문제가 발생한 경우 아예 작업 자체가 실행되지 않았던 것처럼 롤백을 해야 하기 때문이다. 여기에서 추가로 고려해볼 점은, @Transactional을 사용한다고 해서 동시성을 지킬 수 있는 것은 아니라는 것이다. 한 DB 칼럼의 값을 변경하려고 할 때, 엔티티를 조회해온 후 내부 값을 변경하고 다시 영속화하는 흐름을 따른다고 가정하자.@Servicepublic class ItemService { private final ItemRepository itemRepository; public ItemService(ItemRepository itemRe..
지난 Spring REST Docs 적용기에서 만들어 본 API 문서를 EC2 서버에 배포해봤다. build.gradle 파일에 아래처럼 asciidoctor가 생성한 문서를 "static/docs" 경로로 이동시키는 명령어를 추가했다. 프로젝트의 resources/static 패키지에 들어있는 다른 파일들처럼 API 문서도 정적으로 호스팅되길 기대하면서..bootJar { dependsOn asciidoctor from ("${asciidoctor.outputDir}") { into('static/docs') }} 하지만 호스팅되어 있어야 할 URL 주소는 내 문서를 띄워주지 않았다. 문서 파일이 생성된 후에 resources/static/docs 디렉토리로 이동시켰음에도 ..
Spring REST Docs는 API 문서를 작성할 때 필요한 각종 코드 스니펫을 자동으로 생성해주는 도구다. 생성된 스니펫을 조합해 자유도 높은 형식으로 API 문서를 만들어낼 수 있다. 순수한 문서이기 때문에 Swagger처럼 API 호출을 시뮬레이팅할 순 없지만, 테스트 코드를 기반으로 문서화를 지원하기 때문에 겸사겸사 테스트 코드를 작성하는 기회를 마련해주기도 한다. Spring REST Docs는 AsciiDoc과 Mustache 문법을 사용한다. 초기 세팅build.gradle에 REST Docs 관련 설정을 먼저 추가해준다. REST Docs가 생성해주는 스니펫을 어디에 저장할지, 그리고 빌드할 때 어디에 있는 asciidoc으로 최종 HTML 문서를 만들지 등을 설정한다.plugins {..
아무런 문제 없던 코드를 리팩터링하는 도중에 갑자기 "For queries with named parameters you need to provide names for method parameters" 오류가 발생하기 시작했다.. 아래는 오류가 발생한 코드다. 해당 코드는 잘 동작함을 확인했었고 이후엔 수정한 적도 없는데, 다른 변동사항을 확인하기 위해 테스트를 돌려보니 동작하지 않는다. 어디가 잘못되었길래 없던 오류가 나타났을까?@Query(""" SELECT t FROM Theme t JOIN Reservation r ON r.details.theme = t WHERE r.details.date >= :from AND r.details.date findTopThe..
JPA를 사용해보면서 엔티티라는 개념에 익숙해질 때쯤, "DB에 의존적인 설계"라는 표현을 접하게 됐다.@Entityclass User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int age; private String street; private String city; private int zip;} 생각해보니 예시의 User 엔티티는 데이터베이스 테이블의 칼럼과 정확히 일치하도록 필드를 둔 것이고, 따라서 DB에 의존한다는 말이 나온 것이다. JPA가 없는 상황에서 동일한 정보로 User 객체를 만들어야 했다면, 아..