RunToolz iconRunToolz
Welcome to RunToolz!
SQL데이터베이스코드 품질

읽기 쉬운 SQL은 선택이 아니야

미래의 자신 (그리고 팀원들)이 널 미워하지 않게 SQL 쿼리를 포맷하는 법.

RunToolz Team2026년 1월 28일4 min read

쿼리를 물려받아. 한 줄이야. 400자. 여러 join, 서브쿼리, CASE 문이 다 뭉쳐있어.

이해하는 데 행운을 빌어.

SQL 포맷팅은 미학이 아니야. 쿼리가 유지보수 가능한지에 관한 거야.

빽빽한 SQL의 문제

SELECT u.id,u.name,o.total,p.name FROM users u JOIN orders o ON u.id=o.user_id JOIN products p ON o.product_id=p.id WHERE o.created_at>'2024-01-01' AND u.status='active' ORDER BY o.total DESC;

join 조건이 어디야? 뭐가 필터링돼? 각 컬럼이 어느 테이블에서 와?

이제 새벽 2시에 이걸 디버깅한다고 상상해봐.

직접 사용해 보시겠어요?SQL 포맷

같은 쿼리, 읽기 쉬운

SELECT
    u.id,
    u.name,
    o.total,
    p.name
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id
WHERE o.created_at > '2024-01-01'
    AND u.status = 'active'
ORDER BY o.total DESC;

모든 절이 자신만의 줄을 가져. 조건이 정렬돼. 구조가 보여.

작동하는 포맷팅 규칙

절당 한 줄. SELECT, FROM, WHERE, ORDER BY가 각각 자신만의 줄을 받아.

컬럼을 별도 줄에. 긴 SELECT 리스트가 스캔 가능해져.

계속되는 조건 들여쓰기. 여러 WHERE 조건이 정렬돼.

키워드 대문자. SELECT, FROM, WHERE가 테이블 이름과 컬럼에서 돋보여.

일관된 케이싱. 스타일 골라. 고수해.

서브쿼리 포맷팅

서브쿼리는 빨리 지저분해져. 명확히 들여쓰기 해:

SELECT *
FROM orders
WHERE user_id IN (
    SELECT id
    FROM users
    WHERE status = 'premium'
)

아니면 서브쿼리가 복잡해지면 CTE 써:

WITH premium_users AS (
    SELECT id
    FROM users
    WHERE status = 'premium'
)
SELECT *
FROM orders
WHERE user_id IN (SELECT id FROM premium_users)

CTE가 종종 중첩된 서브쿼리보다 명확해.

JOIN 포맷팅

항상 join 타입 명시해. JOIN만 있으면 INNER JOIN이지만 명시적인 게 나아.

SELECT *
FROM orders o
INNER JOIN users u ON o.user_id = u.id
LEFT JOIN shipping s ON o.id = s.order_id

간단한 join은 join 조건을 같은 줄에 놓아. 복잡한 조건은 다음 줄로 나눠.

성능은?

포맷팅은 실행에 영향 안 줘. 데이터베이스 최적화기는 공백을 신경 안 써.

하지만 포맷된 SQL은 최적화하기 쉬워. 구조를 보고, 불필요한 join을 식별하고, 빠진 인덱스를 발견할 수 있어.

읽을 수 없는 SQL은 성능 문제를 숨겨.

팀 표준

스타일 골라. 문서화해. 자동 포매터로 강제해.

다른 스타일들이 있어. 어떤 팀은 쉼표를 줄 시작에 놓아. 어떤 건 모든 걸 대문자로. 어떤 건 안 해.

일관성이 어느 스타일을 고르느냐보다 중요해.


모든 쿼리는 작성되는 것보다 읽혀. 가독성을 위해 포맷해. 팀원들—그리고 미래의 자신—이 고마워할 거야.