동적 컬럼 조회 API의 SQL Injection 방어 (MSSQL)

들어가며 특정 테이블에서 조회할 컬럼을 클라이언트가 골라 넘기는 API가 있다고 하자. 대략 이런 모양이다. SELECT ${col} FROM member WHERE status = #{status} ${col} 자리에 "name"이 들어오면 이름을, "email"이 들어오면 이메일을 조회하는 식이다. 정렬 컬럼이나 검색 대상 컬럼을 유연하게 바꿔야 할 때 흔히 나오는 패턴이다. MyBatis를 쓰면 파라미터 바인딩으로 SQL Injection이 자연스럽게 막힌다고 생각하기 쉽다. 하지만 이 쿼리는 값 조건인 status만 #{}로 바인딩하고, 정작 컬럼 자리는 ${}를 쓰고 있다. 바로 이 차이가 SQL Injection의 위험 지점이다. ...

2026년 7월 21일 PM01:20 · PolarBear

300만 건의 데이터에서 대량 DELETE를 지양해야 하는 이유

들어가며 최근 팀장님과 데이터베이스 최적화에 대해 이야기를 나누었다. 당시 대화의 주제는 “300만 건이 넘는 대규모 로그 테이블에서 불필요한 과거 데이터를 어떻게 정리할 것인가?” 였다. 나는 이 질문을 듣고 바로 조건문을 달아 DELETE 쿼리를 날리면 된다고 생각했지만, 깊게 생각해보지 않은 1차원적인 답변이었다. 내 답변을 듣고 난 후의 팀장님의 대답은 “대용량 환경에서는 DELETE 쿼리를 사용하는 것이 능사가 아니라는 것” 이다. 이 내용을 주제로 해결책과 근본적인 아키텍처까지 정리해 보고자 한다. 300만 건의 로그 정리 방법 팀장님이 내게 다음과 같은 질문을 던지셨다. ...

2026년 3월 23일 PM11:28 · PolarBear