IT 관련/Database

데이터 베이스 이 정도는 알고 사용하자... #1

nullzone 2022. 3. 2.
반응형

오늘부터는 시간이 되면...

데이터베이스를 사용하면서 흔히들 하는 실수를 이야기 해 보려 합니다.


* 근래에 개발을 시작하는 분들이나, 최근 몇년동안 개발에 입문 하시는 분들에게는

  뭐 굳이 데이터베이스를 따로 공부 할 이유가 있겠는가 하실 수도 있지만,

  개발을 조금 더 깊게 공부 하시려는분들은 한번쯤 읽어 보셨으면 합니다.

  
* 이 글을 쓰게 된 계기는 간혹 프레임웍을 사용 할 수 밖에 없는 상황이 되는데...
  인테넷에 참고 하려는 대부분의 글들이 프레임웍을 개발 툴 사용법을 익히는 듯이 설명되어 있어서..
  특히나 데이터베이스 관련 사용법들을 보면... 이런식으로 사용 하면.. 안될텐데 라는 생각이 들때가 있습니다

  단언하건데... 이런 학습방법이 나중에 독이 될 수 있다는 것을 말씀드리고 싶습니다. 

 

  물론 현실에서 마주치게 되는 무수한 벽들이 있을 수 있고.. 개개인들이 생각하는 훌륭한(?) 개발자의 모습이

  서로들 다름을 인정합니다.  제가 현실을 부정하려는 의도는 없습니다.    

 

* 글의 내용은 전혀 어렵지 않고... 깊게 다루지 않고,

  실전에서 자주 사용되는 부분들만, 얕고 넓게 언급해 보려 합니다. 

 

1. 쿼리 문제..
   사실 대부분이 쿼리문에 문제가 심각하다.

   1-1. 조건절 컬럼값을 변경해서 비교 하는 경우...
        where column = :value 
        where function(column)   = :value    (X)
        where substring(column)   = :value   (X)

        정말 지겨울 정도로 많습니다...
        항상 비교시 대상 column은 변경없이 사용한다 라고 공식으로 외워두세요...

        where column   = substring(:value)    
        where column   = function(:value)     

 

  예를들어 설명해 보자....

  만일 1990년1월 1일 ~ 1990년 12월 31일 사이 생성된 자료를 조회 하고자 한다.

       아래와 같은 쿼리를 사용하는데

        where DATE_FORMAT(createTime, '%Y-%m-%d')  >= '1990-01-01'     

           and DATE_FORMAT(createTime, '%Y-%m-%d')   <= '1990-12-31' 

 

       반드시 테이블의 컬럼 값은 변경 하지 말고, 아래처럼 사용하자....

        where createTime  >= STR_TO_DATE('1990-01-01', '%Y-%m-%d %H:%m:%i')   

           and createTime  < STR_TO_DATE('1991-01-01', '%Y-%m-%d %H:%m:%i')

 

날짜-시간 비교의 경우 오라클에서 비번하게 TO_DATE, TO_CHAR 함수를 용감하게 컬럼 값에 빈번하게

사용하는데 제발... 이런 부분은 초보중에 초보가 하는 짓이다...

결과가 정확하면 됬지 뭐!!! -- 이렇게 생각 하시는 개발자가 있으시면... 아래 글들은 읽지 마세요...

왜? 이렇게 쓰면 안될까?

만일 조회 하고자 하는 테이블에 데이터가 100만 건이 있다고 하자...

위의 잘못된 쿼리를 사용 하면 database에서는 내부적으로 100만건의 데이터를 모조리 불러와서 컬럼에

들어 있는 데이터(100만건) 모두를  변경해서 불러오고 나서야 조건을 비교 하게 된다. 

만일 해당 컬럼에 인덱스가 걸려 있다면.... 이 인덱스는 무용지물이다. 

 

난 그런식으로 사용하지 않는다라고 말하지만 이런 경우는 정말 많다.
위의 예는 확실하게 눈에 보이지만.. 조금만 생각해 보면 이런 잘못된 경우의 쿼리가 무수히 많다. 

 


 1-2. NULL 값에 대한 무지...
       java 를 사용해보셨던 분들에게 가장 많은 오류 메세지는? null pointer exception 일겁니다.

       말 그대로 변수에 값이 assign 되지 않아서 해당 변수의 포인터가 null 이라는 에러입니다. 
       데이터 베이스에서 null value는 특이한 값이며, 당연히 이에 따른 처리는 확실하게 해주어야 합니다.

      * 사실 null 값과 관련되어서는 테이블 설계자가 초기에 테이블 설계시 확실하게 정의 되어야 합니다.

        null값이 허용되는 컬럼은 가능한 적게 디자인 되어야 한다는 것이 제 생각입니다.

        뒤에 언급할 수도 있겠지만, 데이터 타입은 근래 개발자분들에게 심각한 문제입니다. 

 

      null 값이 허용되어 있는 컬럼에서는 null값의 처리를 확실하게 해주어야 합니다. 

 

      1990년1월 1일 이후에 생성된  자료를 조회 하고자 한다. (단, createTime 컬럼에 null이 허용된다면...

       아래와 같은 쿼리를 사용하는데

        where createTime  >= STR_TO_DATE('1990-01-01', '%Y-%m-%d %H:%m:%i')   

 

       반드시 테이블의 컬럼 값이 Null 값을 확인 해서 조건절에 넣어주셔야 합니다.....

        where createTime  >= STR_TO_DATE('1990-01-01', '%Y-%m-%d %H:%m:%i') 

           and createTime  IS NOT NULL

 

     * NULL값은 대소 비교, 사이즈 등등 모든 연산이 불가 합니다.
      대부분의 함수, 연산이 불가하며, 결과 값도 예측(?)이 불가합니다.

      오직 ISNULL, IS NOT NULL, ISNULL() ... 등 db에서 제공 하는 NULL function만이 가능합니다.

      그러므로 null 값이 허용되는 컬럼을  where 문에 사용시 반드시 null 값에 대한 처리를 해주어야만 합니다.
      마찬가지로 where 절뿐이 아니라  Group by, Order by 에 이용 할 때도 반드시 주의 하여야 합니다.

 

      많은 개발자들이 눈에 쉽게 보이는 결과 값에서 NULL 값이 나오는 경우, 이를 처리 하지만,
      통계, 숫자(갯수, 길이, 평균값... 등등)를 결과로 쿼리 할때... NULL값 오류가 눈에 직접적으로

      보이지 않기에  그냥 모르고 넘어가는 실수가 꽤나 있는 편입니다.
    

     예를 들어서 어떤 데이터의 평균 값을 구할때도 (AVG함수와 같은 경우) 대상 데이터에 null값 데이터가

     포함되는지 여부를 실수 하여서  잘못된 값을 구하는 경우를 심심치 않게 발견하게 됩니다... 

 

     * 제가 null값에 대해서 설명 할때... null 이 빈문자열도 아니고... 스페이스는 더더욱 아니도..

       그냥 아무것도 없는 (프로그래밍적으로 말하면 아직 포인터에 값이 할당되지 않은 상태?)

       그냥 NULL인 상태라고 말합니다.

 

     * 실제 DB를 이용하는 개발자가 아닌 전문적으로 DB설계를 하시는 분들은

       이런 실수를 거의 하지 않는데...

      근래는 DB설계에 대한 전문 인력 없이 일반 개발자(소위 어느정도 고참급?)들이

      쉽게 테이블을 만들다 보니...   Primary Key Column이나 default 값을 설정한 컬럼 외에는

       대부분 null 허용 컬럼으로 만드는 경우가 많습니다.
       

       위에 언급한 실수를 유발하게 만드는 건 테이블 구성을 잘못하신 분들의 책임일 수도 있습니다.

       설마 이렇게 null 허용 컬럼에 용감하게 인덱스 거시는 분들도 가끔 봅니다.

 

       여담으로 몇몇 프레임워크라고 발표 되고 실제 사용 것들이 개발자들 편하라고(?)
       DB관련(ORM..ㅡ Query Builder...) 모듈을 제공 하는데... 모듈의   내부를 살펴보고
       참... 암울한 적이 한두번 있었습니다.

       물론 제가 많이 사용되는 frameWork들을  왈가 왈부 할만한 실력은 전혀 없습니다만...

 

반응형

댓글