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