포스트

2021-09-13-TIL

2021-09-13-TIL

MySQL

일별/월별/연도별 쿼리

날짜 컬럼을 원하는 단위로 잘라서 GROUP BY한다. DATE(created_at)은 일 단위, DATE_FORMAT(created_at, '%Y-%m')은 월 단위, YEAR(created_at)은 연 단위로 묶는다. 다만 WHERE DATE(created_at) = '2021-09-13'처럼 조건절에서 컬럼에 함수를 씌우면 그 컬럼의 인덱스를 쓰지 못하므로, 조건은 created_at >= '2021-09-13' AND created_at < '2021-09-14'처럼 범위로 쓰는 편이 낫다.

1
2
3
4
SELECT DATE_FORMAT(created_at, '%Y-%m') AS month, COUNT(*) AS orders
FROM orders
GROUP BY month
ORDER BY month;
  • https://pythonq.com/so/mysql/2379

시간 더하기, 빼기 (DATE_ADD, DATE_SUB)

DATE_ADD(date, INTERVAL 7 DAY), DATE_SUB(NOW(), INTERVAL 1 MONTH)처럼 INTERVAL 값 단위로 날짜 연산을 한다. 단위에는 SECOND, MINUTE, HOUR, DAY, MONTH, YEAR 등이 있다. 최근 30일 데이터를 조회할 때 created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)처럼 쓴다.

  • https://extbrain.tistory.com/58

실수로 대량 업데이트

우선 RDS설정에 롤백이 가능하도록 특정 시점(스냅샷)이 저장되는지 확인한다. 저장되지 않는다면 덤프를 떠놓은 파일이 있는지 검토한다. 그것마저 없다면…

이를 방지하기 위해서는 우선

  • https://www.ilifo.co.kr/boards/article/59

복구 수단부터 보면, RDS는 자동 백업이 켜져 있으면 보존 기간 안의 특정 시점으로 복원(point-in-time recovery)할 수 있다. 다만 기존 인스턴스를 되돌리는 것이 아니라 새 DB 인스턴스를 만드는 방식이라, 복원한 인스턴스에서 필요한 데이터만 골라 원래 DB로 옮기는 작업이 따로 필요하다.

예방 수단은 다음과 같다.

  • 직접 수정 쿼리를 칠 때는 트랜잭션을 열고(START TRANSACTION) 실행한 뒤, 영향받은 행 수를 확인하고 나서 COMMIT한다. 예상과 다르면 ROLLBACK한다.
  • 실행 전에 같은 WHERE 조건으로 SELECT COUNT(*)를 먼저 돌려 대상 행 수를 확인한다.
  • MySQL 클라이언트의 --safe-updates 옵션을 쓴다. MySQL 문서에 따르면 이 모드에서는 키 값으로 대상 행을 지정하거나 LIMIT을 붙여야만 행을 수정하거나 삭제할 수 있어, WHERE를 빠뜨린 UPDATE, DELETE가 거부된다.

특정 컬럼의 값으로 다른 컬럼의 값을 업데이트

UPDATE users SET nickname = name WHERE nickname IS NULL;처럼 SET 절의 오른쪽에 같은 행의 다른 컬럼을 쓴다. 다른 테이블의 값으로 갱신할 때는 UPDATE a JOIN b ON a.id = b.a_id SET a.col = b.col 형태의 다중 테이블 UPDATE를 쓴다.

  • https://iwordpower.com/update-column-in-mysql/

BOOLEAN TYPE

MySQL에는 별도의 불리언 타입이 없다. MySQL 문서에 따르면 BOOL, BOOLEAN은 TINYINT(1)의 동의어이고, 0은 거짓, 0이 아닌 값은 참으로 본다. 그래서 TRUE, FALSE는 각각 1과 0의 별칭이고, 컬럼에 2 같은 값도 들어갈 수 있다는 점을 알아 둬야 한다.

  • https://freegians.tistory.com/entry/MySQL-BOOLEAN-TYPE-use-tip

Spring MVC

@RequestParam(defaultValue = "10") int size처럼 기본값을 지정하면, 파라미터가 아예 없을 때뿐 아니라 ?size=처럼 빈 값으로 들어올 때도 기본값이 쓰인다. RequestParam Javadoc은 defaultValue를 요청 파라미터가 없거나 값이 비어 있을 때의 대체값으로 설명한다. 링크된 질문이 바로 빈 값에도 기본값이 적용되는지에 관한 것이다.

  • https://stackoverflow.com/questions/12296642/is-it-possible-to-have-empty-requestparam-values-use-the-defaultvalue

JPA

@Transactional

@Transactional은 Spring AOP 프록시로 동작한다. 그래서 같은 클래스 안에서 this.method()로 호출하면 프록시를 거치지 않아 트랜잭션이 적용되지 않고, 이 글을 쓸 당시의 Spring 5 기준으로는 public 메서드에만 적용된다(Spring 6부터는 클래스 기반 프록시에서 protected, 패키지 접근 메서드도 지원한다). 롤백은 기본적으로 unchecked 예외(RuntimeException, Error)에서만 일어나고, checked 예외에서도 롤백하려면 rollbackFor를 지정해야 한다.

  • https://javabom.tistory.com/103

MyBatis

@Mapper instead of XML mapper

MyBatis는 SQL을 XML 매퍼 대신 매퍼 인터페이스의 애너테이션(@Select, @Insert, @Update, @Delete)으로도 쓸 수 있다. 짧은 쿼리는 인터페이스에 바로 적어 파일을 오가지 않아도 되지만, 동적 SQL이나 긴 쿼리는 XML이 읽기 쉽다. MyBatis-Spring-Boot에서는 인터페이스에 @Mapper를 붙이면 매퍼 빈으로 등록된다.

1
2
3
4
5
@Mapper
public interface OrderMapper {
    @Select("SELECT * FROM orders WHERE id = #{id}")
    Order findById(long id);
}
  • https://codingnojam.tistory.com/27

기타

29CM 기술 블로그의 유저 주문 취소 기능을 Java로 전환한 과정을 다룬 글이다.

  • https://medium.com/29cm/%EC%9C%A0%EC%A0%80-%EC%A3%BC%EB%AC%B8-%EC%B7%A8%EC%86%8C-%EA%B8%B0%EB%8A%A5-java-%EC%A0%84%ED%99%98%EA%B8%B0-d218e5ecb874
참고한 자료외부 출처 6

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다