Thinking in Data/[DL] DataSQL

[SQL수다] #002. SQL 작성하기 전 데이터를 그려라

띤킹인 2020. 9. 1. 04:31

1. 시작

SQL 작성한다는 것은 데이터베이스의 테이블 데이터로 부터 데이터를 그리며 작성하는 것이다.

오랜 경험을 바탕으로 SQL을 어떻게 작성하는지에 대한 대답에 대해 장황한 설명보다 이 말이 더 간결하고 명확하다고 생각한다. 이번 글에서는 해결해야 할 문제에 직면하였을 때, SQL을 적성하기 전에 먼저 소스데이터와 결과 데이터를 어떻게 바라보는지 설명한 후, 무엇을 그려야 하는지 그 데이터를 이야기하고자 한다.

SQL 개발에 능숙한 개발자들은 주어진 문제에 대해 동시에 머릿속으로 데이터 그림을 그린다고 보아야 한다.  그들은 자연스럽게 채득한 개념을 설명하는데 어려워 한다. 어떤 이는 많이 짜보면 알 것이라고 이야기하곤 한다. 하지만, 당장 직면한 문제를 해결해야하는 초급자들에게는 도움이 되지 않는 답일 뿐.  많이 작성해 보는 것은 좋은 것은 맞지만, 작성하면서 스스로 어떻게 작성해야하는지 방법을 찾아가는 노력을 해야만 얻을 수 있는 것을 알려주지 않는다.

앞으로 진행되는 단계별로 구분해서 설명하는 것이 어색할 수 있다. 하지만, 이 글은 SQL 개발을 시작하거나 중급으로 넘어가는 개발자들을 위한 것으로, 단계별 구분 동작은 한번쯤 자신의 SQL 작성하면서 어떤 기준으로 어떤 순서로 작성하는지를 한번쯤 되집어 볼 수 있는 기회가 될 수 있다고 본다. 

2. 테이블과 데이터셋

테이블과 데이터셋에 대해서 먼저 정의해 보자.

테이블 데이터는 물리적인 데이터베이스 저장되어 커밋된 상태의 데이터를 의미하며, 데이터셋은 좀더 추상적인 개념으로 디스크에 존재하는 데이터와 구분하기 위하여 메모리에 올라온 상태의 데이터라는 의미를 갖는다. 

DBMS는 처리해야할 SQL을 받으면 가장 먼저하는 것이 SQL에 대한 구문 파싱을 수행한다. 파싱으로 구문이 분리되면, 어떤 테이블을 읽어야 하는지 이해하려고 한다. 또한, 해당 테이블에 어떤 컬럼값에 조건에 맞는 대상인지 판단하려고 노력할 것이다. 테이블은 디스크로 부터 4KB 또는 8KB 단위로 관리되는 블록 또는 페이지 단위로 읽어들여 DBMS의 공유 메모리 버퍼에 로드한다. 공유 메모리 버퍼에 올라온 데이터에서 SQL 문의  조건절에 명시된 컬럼의 조건에 맞는 레코드을 선택한다. 선택된 레코드는 SQL에 명시된 다양한 함수나 연산을 처리한 다음 최종 결과 데이터를 만들어 낸다. 대부분의 함수나 연산에 의해 만들어진 데이터는 테이블에 존재하는 값을 아니다. 테이블에 저장되어 있는 상태가 아닌 실시간으로 계산된 상태의 가공된 데이터로이며 공유 메모리 버퍼에 존재한다는 것이 핵심이다. 즉, 가공된 데이터는 물리적인 디스크에 저장되어 있는 상태의 데이터와 다르다. 디스크에 저장되어 있는 상태가 테이블 데이터라고 하는 것이고, 가공이 되었든, 가공이 안되었든 간데 공유 메모리 버퍼에서 SQL에 명시된 대로 처리되어 만들어지는 데이터는 더 이상 테이블의 데이터이라고 할 수 없다. 프로그래밍에서도 파일은 디스크에 저장되어 있는 상태를 의미하고, 파일이 메모리에 로드된 상태를 인스턴스라고 하며, 데이터베이스에서도 마찬가지로 공유 메모리 버퍼에 존재하는 상태의 데이터를 인스턴스라고 한다.

앞으로, 물리적인 디스크 상태의 데이터가 아니라 메모리 상태의 데이터인 데이터 인스턴스이면서 테이블과 같은 형태의 컬럼과 하나 이상의 레코드를 갖는 데이터들을  데이터 인스턴스(data instance) 또는 데이터셋(dataset) 이라고 지칭할 것이다. 그 동안 보아온 초급자들이 레벨업을 하기 어려운 이유를 보면, 바로 테이블의 스키마에 갇혀 버린 채 SQL을 작성하고 있다는 것을 알 수 있었다. 테이블은 디스크의 상태에 고정된 스키마를 갖고 있는 반면 데이터셋은 SQL을 어떻게 작성하느냐에 따라 무수히 많은 형태의 가공된 데이터를 만들어 낼 수 있다는 점을 반드시 기억하길 바란다. 

대표적인 SELECT 문을 이해할 때, 고정된 테이블을 로드하고 조인하고 조건절을 처리하는 기능만 이해할는 것이 아니라 더 강력한 기능인 데이터를 가공할 수 있다는 것을 이해하는 것이 중요하다는 것이다. 또한, 이것이 데이터를 그리기의 시작이다.

3. 아는 것과 모르는 것

SQL작성한다는 것을 실무에서는 개발한다는 말로 이야기한다. SQL도 어면히 데이터를 관리 및 처리를 하기 위한 Language임은 자명하다. 지금 데이터베이스의 데이터에 대하여 SQL로 무엇인가를 만들어 내야하는 상황이라면 명확한 목적/문제를 마주하고 있다는 것이다. 금 풀어야할 문제가 앞에 놓여 있다면, 명확한 것은 단 두 가지이다. 바로 문제를 위해 주어진 소스 데이터와 결과 데이터이다. 나머지는 아직 아무것도 모른다.

명확하다고 하였지만 사실 주어진 문제, 즉 요구사항을 이해하는 것 부터 시작이다. 텍스트로 된 요구사항에서 이 두 가지를 파악하지 못한다면, 무엇을 해결해야하는지 모르고 뛰어드는 것이고, 낯선 도시에서 지도 없이 도심을 해매는 것과 같을 것이다.

4. 소스  데이터

SQL을 작성하기 위하여 소스 데이터를 이해한다는 것은 업무시스템의 개발자라면 업무 요구사항을 읽어 가면서 어떤 데이터를 사용할지를 결정한다는 것을 의미한다. 주어진 요구사항에서 소스 데이터는 데이터베이스에 존재하는 테이블일 수 도 있고, 가상 개념의 데이터일 수도 있다. 가상 개념이라는 것은 물리적인 테이블에 명시된 데이터가 아닐 수 있다는 것이다. 다르게 말하면, 친절하게 어떤 테이블의 어떤 컬럼을 사용해야 한다고 명확하게 제시될 수도 있지만, 또 다른 현실에서는 어떤 테이블이라고 명시되지 않을 수 있다는 것이다. 소스 데이터 자체가 명확하게 제시되지 않는다는 것은 업무의 이해와 시스템의 기능 그리고 데이터의 이해를 바탕으로 추론하는 것과 같다. 주문이 발생하였다면 주문마스터에 데이터가 담겨 있을것이고, 배송처리의 상태 데이터를 대상으로 하다면, 주문배송상태정보 데이터를 읽어야할 수 있다. 주어진 문제로부터 어떤 테이블을 사용해야하는지를 결정하는 단계가 있다는 것이다. 이 테이블을 얼마나 빠르게 결정하느냐가 문제를 해결하는 시간을 단축시켜주는 하나의 요소가 될 것이다. 하지만, 초급자들에게 나타나는 모습을 보면, 어떤 테이블로 부터 시작되어야하는지, 좀더 일반화 시키면 어떤 데이터셋(개념적)으로 부터 시작해하는지를 이해하는데 어려움을 겪고 있는 것이 현실이다.
빠르게 어떤 테이블을 사용해야 하는지를 이해한다는 것은 접근하고 있는 데이터베이스의 소스 데이터를 잘 이해하고 있다는 것이며, 그 테이블에 앉아 있는 데이터들에 대해 이해하고 있는지 묻는 것이라고 할 수 있다. 결국, 업무 시스템에 대한 이해도가 주어진 문제로부터 어떤 테이블들을 사용해야하는지를 알고 있다는 것과 연결되고, 좀더 나가가면 현행 업무 데이터베이스에 대한 데이터 모델을 이해하고 있는지와 연결된다. 결국, 데이터 모델을 이해도가 업무 이해도와 상응하기 때문에 장기적으로 SQL작성에 있어서 데이터 모델에 대한 이해는 반드시 필요하기 때문에 준비해야 한다.

5. 결과 데이터

소스 데이터가 결정이 되면, 요구사항에 대한 결과 데이터가 어떻게 만들어져야 하는지를 이해해야 한다. 소스데이터가 출발지이면 결과 데이터는 목적지이다. 결과 데이터가 주어진 문제에서 요구하는 데이터 셋을 그려놓으면 되기 때문에 정의하기 쉽다. 업무시스템을 놓고 보면 대부분 화면에 뿌려질 데이터셋이 어떻게 구성되어야 하는지를 결정하기 때문에 어려움이 적다.

단순히 테이블의 데이터를 로드한 그대로 결과 데이터로 요구할 수도 있지만, 대부분은 가공되어진 결과를 요구하게 된다. 결과 데이터의 모습은 요구사항에 대한 요청자와 협의하여 결과 데이터의 모습을 확인하여 결정하게 된다.

주어진 요구사항을 분석하여 소스 테이블을 명확히 결정하였고, 결과 데이터의 모습이 명확하게 결정되었다면, 이제 소스 테이블의 데이터로 부터 결과 데이터를 만들어내는 과정을 결정해야 한다. '3. 아는것과 모르는것' 에서 소스데이터와 결과 데이터 외 나머지는 모른다고 하였는데, 이것이 소스데이터 부터 결과 데이터를 만들어 내는 과정을 어떻게 결정하는지에 달려 있기 때문이고, 이 능력이 결국 SQL의 능력을 좌우하게 된다고 생각하기 때문이다.

6. SQL의 고난

필자의 경험에 대해 한 가지 말해 보고자 한다.

선임으로 컨설팅 회사에 입사하여 가장 힘들게 한 것은 SQL을 짜려할 때, 원하는 결과가 나오지 않아 답답한적이 많았다는 것이다. 내 눈은 언제나 문제와 결과에 꽂혀 있었고, SQL 구문을 어떻게 해야 원하는 결과가 나오는지 고민을 하고 있었다. 하지만, 원하는 시간내에 결과를 만들어내는데 어려움이 많아 항상 퇴근이 늦었다. 다행히 주변에 고수분들이 많아서 답답할 때 마다 바로 쫓아가 물어보곤 했었다. 3개월 가까이 질문을 하고 답변을 듣는 과정에서 두 가지를 알게 되었었다.

첫번째는 내 자신이 요구사항을 정확히 이해 못하고 있다는 것이었다. 돌이켜 보면 질문에 대한 답변보다 오히려 그분들이 나에게 질문을 더 많이 하셨었다. 이는 내가 문제를 정확히 이해하고 있지 못했기 때문에 내가 풀어야할 과제를 설명이 필요한 것이었다. 왜 데이터를 이해하지 못했는지는  "현행 데이터 분석 방법"의 사례를 통해 별도로 이야기하도록 하자.

두번째는 풀이 과정을 설명을 듣는데 이해를 못하는 경우가 있었다는 것이다. SQL을 보고 이해를 못한다는 것은 달리 말하면 SQL 구문에서 모르는 문자/단어는 없었지만 왜 이런 결과가 나왔는지가 이해가 안 되었다고 말하는 것이 정확할 것이다. 상황을 좀더 자세히 설명하면, 업무 기능에 대한 SQL이 아니라, 현행 데이터 분석 및 진단, 데이터 이행을 위한 SQL에서 부딧히는 문제였었다. 이것은 요구사항 조차도 스스로 찾아서 만들어야 하고 스스로 데이터를 만들어 내는 경우가 대부분이다.

나름 노력하고 공부했다고 생각했었는데 왜 요구사항을 제대로 이해 못하는 것인지? SQL을 작성할 수 있는데 왜 이런 결과가 나오는지를 이해할 수 없는 경우가 생기는 것인지?

두번째 이슈가 이상하다는 것이었다.

이 때 부터 나만의 SQL을 작성 방법을 찾기 위한 첫 발이 시작이 되었다. SQL 구문과 함수에 대해 다시 확인하면서, 고수와 내 자신과의 차이를 알아가려고 노력 하였었다. 스스로 SQL 문제도 내보고 스스로 풀어보기를 1년쯤 지났을 때, 떠오르는 것이 하나 있었다.

SQL을 작성할 때에 고수들은 머릿속으로 데이터를 그리고 있었다.

7. 고수의 그림

고수들은 데이터를 그린다고 표현하지 않는다. 그냥 많이 작성해본 경험에 의해 작성한다고 한다.

필자가 느낀 것은 업무 데이터를 정확하게 이해하고, 무엇을 처리할지를 정확하게 이해하면서 원하는 결과 데이터를 만들어내기 위하여 그냥 SQL을 작성하는 것이 아니더라는 것이다. 그들은 소스 데이터로 부터 데이터를 가공하고 가공하고 가공하여 결과 데이터를 만들면 되겠다는 것을 예상하고, 어떻게 중간 데이터를 만드러내는지를 생각한다는 것이었다.

너무나 당연한 이야기라고 생각하는 분도 있을 것이다.

1년이라는 시간을 거쳐서 고민했던 것들이 결국 SQL의 구문에 따라 어떻게 데이터셋이 만들어지는지, 함수를 사용할 때 어떤 데이터셋을 만들어지는지를 이해하는 것으로 데이터 그림을 그릴 수 있는 시야가 밝혀지게 된 것이었다.

 

<그림> 소스 데이터 -> 가공 데이터 -> 가공 데이터 -> 가공데이터 ... -> 결과 데이터

 

바로 가공 데이터에 대한 상상력, 즉, 중간 과정의 가상 데이터에 대한 그림을 1~2장을 그릴 수 있느냐, 100~200장을 그릴수 있느냐가 하수와 고수의 차이라는 것이 필자의 주장이다.

 

단적인 예를 들어보자.

본 블로그에 올린 "[SQL Quiz] #R004. 미로 찾기 1" 퀴즈이다. 퀴즈에서는 그림2)에 대한 기본 데이터셋을 SQL로 제공하고 있고, 그림3)과 같은 결과를 얻고자 한다. 자~ 문제를 어떻게 풀 것인가?

 

그림2) 미로 찾기 맵
그림3) 미로찾기 탐색 결과 경로 표시 예시

 

본 글 서두에 설명한 것과 같이 퀴즈에는 문제가 주어졌고, 문제에는 소스데이터와 결과 데이터가 주어졌다. 또한, 하나의 SQL로 작성되어야 한다. 준비된 것은 소스 데이터 뿐 이며, 이 소스만으로 결과 데이터를 만들어 내야 하기 때문에 가공 데이터를 만들어 결과 데이터에 도달해야 한다. 이제 목표는 명확해 졌다. 상상력을 동원하여 중간 데이터인 가상 데이터를 만들어 내야 한다. 가상 데이터를 만드러낼 수 있다면 결과 데이터를 만들 수 있을 것이다.

8. 앞으로 해야 할 것

필자가 SQL에 대해 어려움을 느낄 때 했던 행동은 문제와 SQL구문을 어떻게 작성해야 하는지에 대해 고민하였다고 말하였다. SQL구문을 작성하는데 초점을 맞추는 것은 절대적으로 실력을 키울 수 있는 방법이 아니라는 것을 이해했을 것이다. SQL구문을 어떻게 작성할 것인지를 고민하는 것이 아니라, 중요한 것은 바로 소스 데이터를 어떻게 가공해야하는지를 고민해야 하는 것이었다. 데이터 가공에 대한 이해는 SQL 구문과 함수에 대하여 데이터가 어떻게 처리되는지의 깊은 이해를 바탕으로 한다는 것이다. 앞으로는 SQL구문과 함수의 개념을 가공 데이터를 그리기 위한 관점으로 바라보아야 한다. 그리고 자신만의 개념 정립과 관점을 세워야 한다.

다음 글에서는 SQL문에서 특히 SELECT 문이 갖는 가공 데이터의 기본 형태와 가상 데이터셋에 대해 이야기할 것이다.

댓글수0