회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
안녕하세요. 데이터리안의 윤선미입니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
안녕하세요. 데이터리안의 윤선미입니다.
지독하게 읽기 힘든 SQL 문을 해석해 본 적 있으신가요? 마치 암호를 읽는 것처럼 어렵습니다. 꼭 남이 작성한 SQL이 아니더라도, 과거의 내가 작성한 SQL이 현재의 내 발목을 붙잡는 경우도 있습니다. 아무리 읽어도 도대체 뭘 의도하고 썼는지 모를 때가 있습니다. 제가 작성한 것이라 누구를 욕할 수도 없고요. SQL은 띄어쓰기, 들여쓰기에 거의 규칙이 없다시피 한 언어입니다. 예를 들어 아래 두 코드 블록은 같은 결과를 계산하는 코드입니다.
SELECT day, total_bill
FROM tips
SELECT day, total_bill FROM tips
파이선처럼 들여쓰기와 띄어쓰기를 문법적으로 강제하는 언어를 사용해 봤다면 SQL의 자유로움에 잠깐 해방감을 느낄 수도 있습니다. 그렇지만 곧 남이 써 놓은 SQL 문을 해독하면서 '뭐 이딴 언어가 다 있나...'라고 생각하겠지요. 그래서 이번 글에서는 SQL 문법에서는 강제하지 않지만, 가독성 있는 SQL 코드를 쓸 수 있는 다섯 가지 습관들을 얘기해 보겠습니다.
첫 번째는 SELECT
, FROM
, GROUP BY
, HAVING
, AS
, AND
와 같은 SQL 예약어를 대문자로 쓰는 습관입니다. 아래 두 코드 중 어떤 코드가 더 잘 읽히나요? 저는 첫 번째 코드가 더 잘 읽힙니다.
SELECT tip, total_bill
FROM tips
select tip, total_bill
from tips
SQL 언어를 지원하는 에디터를 쓴다면 예약어를 컬럼이나 테이블 이름과는 다른 색으로 강조(하이라이팅)해주기 때문에 굳이 대문자로 쓰지 않아도 잘 보이긴 합니다.
SELECT tip, total_bill
FROM tips
※ 편집기 문제로 코드 블록을 적용하지 않았습니다.
위에 코드 블록도 SELECT
, FROM
에 강조를 해줍니다. 그렇지만 에디터마다 규칙이 다르고, DB 종류마다 함수들 이름도 약간씩 다르기 때문에 제대로 강조가 되지 않는 경우가 많습니다. 특히 DATE_ADD()
같은 날짜 함수는 DB마다 차이가 크게 납니다. 그래서 예약어, 함수 이름 등은 대문자로 써주는 습관을 들이면 쉽게 자신이 쓴 코드를 구분할 수 있습니다.
두 번째는 행갈이를 자주 하는 습관입니다. 아래 두 코드 중 눈에 익숙하고, 잘 읽히는 코드는 역시 첫 번째라고 생각합니다.
SELECT day
, time
, SUM(total_bill)
FROM tips
GROUP BY day, time
SELECT day, time, SUM(total_bill) FROM tips GROUP BY day, time
저는 SELECT
, FROM
, GROUP BY
와 같이 한 라인에 다른 절이 있는 코드를 작성하지 않습니다. 하나의 라인에 코드를 쭉 쓰면 작성할 때야 편하겠지만, 나중에 그 의미를 파악하기 위해 모든 코드를 다 읽어 봐야 합니다. 두 번째 블록의 경우, 모든 코드를 끝까지 다 읽어야 ‘아, 이게 집계를 하기 위해 작성한 코드구나’라고 알 수 있습니다. 하지만 첫 번째 블록의 코드는 각 라인의 예약어만 확인하더라도 작성자의 의도와 코드 구조를 쉽게 파악할 수 있습니다.
세 번째, 행갈이를 더! 자주 하는 습관입니다. 이번에도 아래의 두 코드를 비교해 보겠습니다.
SELECT day
, time
, SUM(total_bill)
FROM tips
WHERE sex = 'Female'
AND smoker = 'Yes'
GROUP BY day
, time
SELECT day, time, SUM(total_bill)
FROM tips
WHERE sex = 'Female' AND smoker = 'Yes'
GROUP BY day, time
위의 예시처럼 코드를 작성하는 것은 주석처리를 할 때 진가를 발휘합니다. 예를 들어 지금은 day
, time
두 컬럼을 집계의 기준으로 사용하고 있는데 이 중에 day
만 남기고 싶다고 가정해 보겠습니다. 그럴 때 라인을 주석 처리하는 방식으로 time
컬럼을 로직에서 제외할 수 있습니다.
SELECT day
-- , time
, SUM(total_bill)
FROM tips
WHERE sex = 'Female'
AND smoker = 'Yes'
GROUP BY day
-- , time
이처럼 가끔 쿼리를 쓸 때 어떤 로직을 제외했다가 다시 포함해야 하는 일이 생길 수 있습니다. 그럴 때 행갈이를 ‘더! 자주’하는 습관이 빛을 발합니다. 주로 예약어에 따라 행갈이를 하기 때문에 무엇이 문제인지 쉽게 파악해서 빠르게 해결할 수 있기 때문입니다. WHERE
절에서도 AND
, OR
이 붙을 때마다 행갈이를 해주면 아래와 같이 활용할 수 있습니다.
SELECT day
, time
, SUM(total_bill)
FROM tips
WHERE 1 = 1
-- AND sex = 'Female'
AND smoker = 'Yes'
GROUP BY day
, time
가끔 SQL을 잘하는 분들을 보면 위와 같이 WHERE
절이 시작하자마자 1 = 1
이라는 아무 의미 없는 조건을 넣어주고 행갈이를 한 다음 AND
로 진짜 필터링 조건을 쓰기 시작하기도 하더라고요. 재미있는 응용인 것 같아 적어봤습니다.
네 번째로는 코드를 쓴 의도를 짧게 적어 놓는 습관을 들이는 게 좋습니다. 특히 서브쿼리가 많아지고 코드가 길어질수록 각 코드 단락이 어떤 의도로 작성되었는지 적어 놓아야 다음에 그 코드를 읽었을 때 이해할 수 있습니다.
SELECT AVG(sales) avg_sales
FROM (
-- 요일별 매출액 합계 계산
SELECT day -- 일별 X 요일별 O
, SUM(total_bill) sales
FROM tips
WHERE sex = 'Female' -- 결제자의 성별이 여성인 경우
GROUP BY day
) daily_sales
주석은 서브쿼리 단위로 쓸 수도 있고, CASE
, IF
조건문 또는 WHERE
절 필터링 조건을 쓸 때도 적어주는 것이 좋습니다. 주로 이런 것들을 주석에 적어주면 좋습니다.
주석을 잘 적는 것도 중요하지만, 결국 코드를 잘 써야 전체를 빠르게 이해할 수 있습니다. 혹시 서브쿼리, 컬럼 Alias를 x
, y
, t
, df
, a
등으로 대충 쓰고 계시지는 않나요?
FROM
절 서브쿼리 이름을 t1
이라고 지었다가 아우터 쿼리 어디에서 t1.x + t2.y
라는 코드를 발견했다고 가정해 보겠습니다. 그 코드가 어떤 동작을 하는지 알려면 저 Alias를 쓴 서브쿼리까지 결국 다시 찾아가야 합니다.
네, 벌써부터 “데이터 분석용 쿼리는 재활용할 일도 많지 않은데, 굳이 그 많은 Alias 작명을 해야겠냐?”라는 아우성이 들립니다. 그렇다면 다음에 그 코드를 다시 볼 일이 생기면 고통을 받는 수밖에 없습니다.
재미있는 건 이런 고민을 저와 독자들만 하는 것이 아닙니다. 구글에 ‘변수명 짓기 팁’을 검색하면 수많은 개발자가 변수명을 잘 짓기 위한 팁을 알려주고 있습니다. 그나마 다행인 건 이름을 짓는 것도 하다 보면 늘기 때문에 갈수록 쉽게 작성할 수 있습니다.
여러 규칙에 관해 얘기했지만, 가장 중요한 것은 내가 같이 일하는 사람들과 합의된 규칙입니다. 아무리 좋은 방법이라도 팀에서 사용하고 있는 컨벤션에 위배된다면, 기존 구성원들을 설득하고 레거시 코드들을 죄다 바꾸는 수고를 하지 않는 한 일단 기존 제도를 따라야 합니다. 아무리 좋은 변수명 짓기 규칙이 있다고 하더라도 기존에 있는 코드 규칙을 완전히 무시하고 본인만 ‘무소의 뿔처럼 혼자서’ 갈 수는 없는 법입니다.
무엇보다 이 코드를 나 말고 누군가가 볼 거로 생각하면서 작성하고 정리하는 것이 중요합니다. 엉망진창인 전임자의 SQL 코드를 보면서 열 받았던 나의 경험이 어느 순간 미래의 후임자가 겪는 일이 될 수도 있기 때문입니다. 사람 일은 모르는 것입니다. 지금 잘 작성한 SQL 코드 한 단락이 미래의 나를 구하게 될지도 모릅니다.