[DB] 모델링 (Modeling) 주의할점

  • 참고사이트

DB 모델링

관련 내용을 알아보던 중 보면 좋을만한 내용이 있어 링크와 나름대로의 정리를 해서 올린다.

현업에서 left join, outer join 을 사용하는 이유에 대한 내용이다.


실제 생활을 그대로 DB로 옮겨 표헌하면 DB의 퍼포먼스를 낼수없다.
outer join 이 걸리면 드라이빙 테이블이 변경되기 때문에 예상과는 다른 실행게획으로 쿼리를 실행해서 속도를 현저히 떨어뜨릴 소지가 있다.

실생활에서는 개념이 Null 일 수는 있지만, DB에서는 그것이 조인이 되는 컬럼을 Null 로 세팅해서는 안된다.

예를 들면, 부부와 자식 이렇게 두 개의 테이블이 있을 때 자식이 없는 부부라면 자식 테이블의 자식의 수 에는 null 대신 없음이나, 0 을 입력해야 된다. (물론 일반적으로 자식명수를 이용해 join 할 경우는 없겠지만)

실제 join 에 사용되는 예시를 들면 아래와 같다.

Oracle에서 outer join 설명할때 구체적으로 사용하는 대표적인 예가 Oracle의 scott 스키마에 있는 부서 테이블과 사원 테이블의 조인하는 것이다.
사원 테이블 중이 아직 미배정 사원이 있어서 사원 테이블의 부서 코드 컬럼이 null로 셋팅된 사원이 있다.
그래서 사원 테이블과 부서 테이블을 조인하면 부서 코드 컬럼이 null인 사원은 나오지 않기때문에 사원도 나오게끔 하기 위해 outer join을 사용하면서 outer join에 대한 구체적인 예시로 든다.
DB 설계자는 미배정을 null로써 표현했지만, null 은 있다, 없다 등 긍정, 부정의 의미가 아니라 모른다는 의미이다. 그리고 부서에 null 이 허용된다면 outer join 사용시 성능에 문제가 발생하고, 미배정은 모른다는 의미가 아니기 때문에 미배정 이라는 값을 두고, 부서명에 미배정을 입력해야 한다.

몇십만건 있는 테이블에서 inner join이 인덱스 태우면 조회할때 10초 면 나올것을
현실적인 개념이란 생각을 그대로 옮긴다는 설계땜에 outer join에 인덱스 못태워서 몇분씩 걸리게끔 해서 나온다면
그걸 보는 사람에게 뭐라고 할것인가? 그걸 보는 사람에겐 설계가 오류가 아니라고 설명시킬순 없다.

자신이 보는 관점에서 나는 이렇게 하는게 설계상으로 맞아 이런다 할지라도. 그걸 사용하는 사람 입장에서 제 성능이 안나오면..자기가 아무리 그렇게 주장해도 그렇게 받아 들일 수 없다.

왜냐하면 사용하는 사람은 이런 관계형 데이터 베이스의 개념을 모르기 때문이다.
즉 나는 그런거는 모르겠고 내가 원하는게 빨리 나오길 바라는 사람들이다.

그런 사람들 앞에서 현실생활에서는 개념이 이렇고 그래서 이렇게 했습니다..라는 식의 말은 통하지 않는다.

설계란 것은 개념과 그 개념을 구체화시킬때 최대한의 퍼포먼스를 끌어내는 방법으로 해야 하는 하고
null을 들어가게끔 해서 outer join을 걸게 하고 그로 인해 조회가 오래 걸린다면 분명 설계가 잘못됐다고 볼수 밖엔 없다.
구체화하는 방법에서 좀더 성능을 끌어 올릴수 있는 방법으로 설계할수 있음에도 불구하고 그게 현실세계와 맞지 않다(그렇다고 아주 안맞는 것도 아닌데)는 이유로 외면했기 때문이다.

데이터는 누적이다.
현 상태를 그대로 유지하는 상황은 그리 많지 않다.

앞으로 누적이 된다는 마인드로 설계하면 outer join을 사용하면 시간이 흐르면 흐를수록 처리 속도는 떨어지게 될것이다.
outer join이 속도가 왜 떨어지냐면, 우리가 index를 사용할때 null 컬럼은 index를 태우질 못한다.
이것도 DB 입장에서는 올바르게 작업한것이다. 왜냐하면 값 자체를 모르는데 어떻게 인덱스화 시킬수 있냐.
거기서 차이가 확 나게 된다. 인덱스를 접근하는게 아니라 전체 스캔이든 부분 스캔이든 테이블을 직접 스캔해야 하니까

테이블을 직접 스캔하는 것은 상당히 공수가 크게 들어가는 작업이다.
일일이 하드 디스크에서 데이터 블록을 읽어와서 그걸 하나하나 따져야 하기 떄문이다.

인덱스를 사용하면 해당 행의 주소가 있기땜에 직접 접근할수 있다.
즉 데이터 양이 점점 많아질수록 속도가 떨어지는것이다.

null은 모름이고 모름은 필터링 대상이 될순 있으나 모름은 조인 대상이 될수 없다.
있는지 없는지도 모르는데 어떻게 관계를 지어서 연결해야 하냐
차라리 나는 몰라..라는 의미로 모름을 구체화한 데이터로 만들고 조인을 하는게 더 개념적으로 맞다.

요약

  • 조인에 사용하는 컬럼은 null 값이 입력되지 않도록 한다. (개발 중 기획 등이 변경되어 추가 기능이 생기지 않는 한)
  • outer join을 사용하면 속도가 떨어질 수 있다.

Leave a comment