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
댓글
아직 댓글이 없습니다