티스토리 뷰

월간 미생

2020 상반기 회고 (1~6월)

H!GHR 2020. 11. 22. 20:37

일이 많아지면서 잦은 야근과 (요근래 잠시 일이 몰렸네...가 아니라 찍어내느라 계속 많다...)

업무 외적인 것에 신경쓸 일이 많아지다보니 블로그를 소홀히 했다.

상반기가 훌쩍 지났지만 지금이라도 기억을 더듬어가며 반성의 시간을 가져야겠다.

 

여러 DB의 호환 문제


회사에서 오라클, MariaDB, TiberoDB, Altibase 모두 사용중이다.

정확히는 계약하면서 고객맞춤형으로 DB를 제공하다보니 여러가지를 사용해볼 수 있는 기회가 생겼다.

전 직장에서는 Altibase를 사용해봤고, 오라클과 mysql은 개인프로젝트와 기존 개발시에 활용해봤으니

새로 접해본 것은 TiberoDB 뿐이었다.

MariaDB는 MySQL 기반이라 그런지 MySQL과 상당히 유사했고 오라클과 다른 문법들이 많았다.

Altibase와 Tibero는 오라클의 영향을 받아서인지 오라클 문법이 어느정도 통용되는 것을 확인할 수 있었고,

오라클과 마리아DB의 호환 위주로 작업을 진행했다.

1) 오라클 문법들의 호환 불가

- 기존 오라클 문법들 중 MariaDB까지 호환이 가능한 것들은 손쉽게 변경할 수 있었다. (ex. CONCAT 같은거)

- 정 바꿀 수 없는 몇몇이 있었는데 (오라클 : TO_CHAR / 마리아 : CAST 등) 얘네는 property 파일에 저장된 DB 기준으로 mybatis에서 분기를 태워 쿼리를 나눴다.

<choose>
    <when test='DbProvider.equals("MARIADB")'> 
          AND    TIMESTAMPDIFF(month, FIRST_DATE, LAST_DATE)
    </when>
    <otherwise>
          AND    MONTHS_BETWEEN(FIRST_DATE, LAST_DATE)
    </otherwise>
</choose>

- 마지막으로 호환도 애매한 애들은 (오라클 : PIVOT 같은거) 데이터를 불러와 API에서 처리했다.

2) NULL sorting 기준

SELECT INSERT_DATE FROM SAMPLE_TABLE ORDER BY INSERT_DATE

NULL 값이 있는 위의 쿼리를 오라클과 마리아DB에서 각각 돌려보면

오라클은 NULL 값이 가장 나중에 나오고 마리아DB는 가장 처음에 나온다.

sorting 된 결과를 그대로 불러와 뿌려줘야할 때 null 값들의 위치선정도 중요하다.

오라클은 NULLS LAST, NULLS FIRST / 마리아DB는 컬럼명 앞에 마이너스를 붙여주면 위치를 조정할 수 있다.

(ORDER BY INSERT_DATE NULLS LAST / ORDER BY -INSERT_DATE)

하지만 이러면 order by를 통해 sorting하는 부분마다 mybatis상에서 분기를 나눠줘야하는 문제가 있다.

null값이 필요한 상황이면 DB 상관없이 어떻게 정렬을 할 수 있을까?

SELECT INSERT_DATE FROM SAMPLE_TABLE ORDER BY COALESCE (INSERT_DATE, SYSDATE)
 
SYSDATE는 타입 일치를 위해서 써준 것이므로 VARCHAR나 NUMBER의 경우 공백이나 0으로 치환 가능하다.

이렇게 쓰면 오라클이나 마리아나 동일하게 NULL값들은 맨 끝으로 모아진다.

하지만 한번 가공이 들어가기 때문에 정상적인 INDEX는 타지않아 성능상 별로인듯 싶기도하다.
 
인덱스 없는 컬럼이라면 써봄직할지도..?
 

3) 조금 더 예민한 MariaDB(?)

SELECT *
FROM (SELECT EMP_NO
     FROM EMP_TEMP)

오라클에서 위처럼 쿼리를 돌리면 아무 문제없이 잘 돌아간다.

하지만 마리아DB도 같을까?

역시 생각한대로 되는건 없다...

내용대로라면 LIMIT 0,200이 필요하다는거 같은데 이걸 이어서 라인에 추가해도 에러는 계속 뜬다.

왜 그러는걸까 하다가 서브쿼리에 Alias를 지정해줘봤다.

SELECT * FROM (SELECT EMP_NO FROM EMP_TEMP) T

이런식으로 별칭을 지정해주면 에러는 나지 않는다.

(근데 LIMIT 문법 오류 같은데 별칭을 지정해야 문제가 해결 되는건 이해가 가지 않는다... 구문이 이어진다고 생각해서 추가로 뒤에 문법을 덧붙이라고 에러가 난게 아닐까 추측해본다)

4) HINT 사용의 애매함

속도가 너무 안나는 쿼리를 SQL 전문가 가이드를 보면서 나름의 튜닝 계획을 세웠다.

실행계획을 확인하고 과도한 NL조인으로 속도가 느려진게 아닐까 하는 혼자만의 상상으로

오라클 힌트를 적용해 Hash 조인으로 바꿔버렸다.

속도는 개선되었지만 여러DB를 사용하면서 힌트 적용도 여러번 해야하는 것인가 하는 고민이 생겼다.

그러면서 힌트에 대해 조언을 청한 결과, 힌트는 최후의 수단으로 사용하고 되도록이면 옵티마이저가 하고픈대로

냅두는게 낫겠다는 결론을 내렸다.

그 순간 최적의 선택지를 보여주는건데, 힌트로 강제변환해버리면 나중에 데이터가 많아질 때

또다른 이슈가 생기지 않을까 하는 생각때문이었다.

힌트는 히든 카드로 사용하고 근본적인 튜닝을 바꾸도록 진행시켜야겠다.

 

자체 툴 사용의 장단점


상반기에는 주로 회사에서 쓰는 자체 툴 사용법을 익혔다.

자체 툴은 화면 그려주는 프론트 쪽과 인쇄 출력 쪽인데 나름의 장단점이 있다.

장점은 간단한 개발은 최적화 되어있다.

버튼에 대한 클릭 이벤트나 리얼그리드 기반으로 데이터 표를 만들기 위해서 몇 번의 클릭만으로 자동완성된다.

따라서 간단한 CRUD는 자체 툴로 뚝딱뚝딱 만들 수 있다.

하지만 조금 디테일하게 만들기는 여간 까다로운게 아니다.

가령, 데이터에 따라 그리드 헤더를 다르게 주고 싶은데 해당 기능이 없다면 직접 만들어야한다.

하지만 Realgrid 기반을 자체 툴로 한번 더 가공해서 해당 기능여부를 두번에 걸쳐 찾아야한다...

자체 툴을 사용하여 자체 API에 해당 기능이 없다면 최대한 그 안에서 어떻게든 돌려돌려 써먹을 수 있는 방법을 찾고,

안된다면 Realgrid API를 찾아서 그 기능이 있다면 쓰고 아니면 또 그 안에서 잔머리를 굴려서 사용하도록 해야한다.

양날의 검같은 존재지만 회사 국룰이기에 + 국룰은 누구든 바로 수정이나 사용 가능하니깐 열심히 익혀뒀다.

물논 여길 나간다면 아무데서도 쓸 수 없는 휴지조각이겠지만...

 

이펙티브자바의 활용 


이펙티브 자바를 읽기 시작했다.

(초반에만 찔끔읽고 쿼리 튜닝이 좀 필요할 듯 싶어 현재는 다른 책을 읽고 있다...)

기술서적은 읽다가 오오 이거 쓸만하겠는데? 싶은건 다 직접 써보고 싶은 욕구가 넘쳐나게 한다.

이번의 희생량은 빌더 패턴이었다.

데이터를 가공해 프린트하는 곳으로 전달하는 API 였는데 같은 내용이면서 소스도 길고 이걸 두군데서 중복으로 사용하고 있었다.

소스 길이 좀 줄여볼겸 빌더 패턴 연습도 할겸 유지보수의 편의를 위할겸

겸사겸사겸겸사사 빌더 패턴을 위한 유틸 클래스를 따로 만들었다.

당시에는 가독성 향상 + 활용했다는 뿌듯함이 앞섰는데, 나중에 해당 로직에 다른 기능을 추가하는 수정사항이 생겼을 때 정말 간단하게 처리되어 효율성까지 있었다.

빌더 패턴이 있는 클래스에 소스 추가 -> 빌더 패턴 사용시 해당 메소드 사용(?) -> 끝

추가하는 작업이 정말 간단한 절차로 끝이 났다.

앞으로도 유지보수가 잦은 듯 싶으면 해당 패턴을 활용해 효율적인 유지보수가 되도록 해야겠다. (라고 생각은 했다)

ps. 빌더 패턴은 생성 패턴 중 하나라서 주로 매개변수가 많은 생성자에 사용하면 가독성 면에서 좋아진다.

createEmployee('1000', '114455', '20200302', 'M', null, null)
newEmployee.Builder()
	.addCompany('1000')
        .addEmpno('114455')
        .addBirthdy('20200302')
        .addSex('M')
        .build()

 

결론


백엔드 개발자의 미덕은 DB, 서버, 프로그래밍 언어 삼위일체가 아닐까 생각한다.

외근나갔을 땐 폐쇄망이라서 직접 서버 접속해 로그볼 일이 잦았다.

물론 끽해야 로그 확인 정도라 리눅스를 다이나믹하게 사용한 것은 아니지만 그래도 곁에 있는 친구였는데

요즘은 VSCODE에서 깃 풀 받을 때, 아니면 노드 서버 실행할 때 뿐이다.

서버쪽은 개인 포트폴리오로 작업하면서 공부를 이어가야겠다는 생각이 든다.

그리고 여유있을땐 이거저거 시도하고 삽질도 해보면서 실력도 향상되고 덩달아 리팩토링도 자연스레되면서

코드의 질도 향상 되는 느낌이 들었는데 요즘(뿐만 아니라 앞으로도 쭈욱...) 계속 바빴기에 이것저것 시도는 꿈도 못꿨다

들어오는 일들은 죄다 하루살이라 오늘내일하며 숨넘어갈라그러는데 품질 향상을 위한 삽질은 꿈도 꿀 수 없다.

삽질로 보내는 시간에 붕대질이나 심폐소생술 한번 더 하는게 더 이득이고,

어찌저찌 숨을 붙여놓으면 다음 친구 소생시켜야해서 후속 조치(리팩토링)는 고이 접어 나빌레라...

일따로 공부따로의 마음가짐으로 내년을 기약해야겠다 (현재 11월말...ㅠㅠ)

'월간 미생' 카테고리의 다른 글

2021 상반기 회고 (1~6월)  (0) 2021.08.04
2019 하반기 회고 (7~12월)  (0) 2020.01.11
2019 상반기 회고 (1~6월)  (2) 2019.05.15
댓글