일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- navercloud
- object storage
- 네이버클라우드
- docker
- Java
- ngrinder
- DBDocs
- Naver Cloud Platform
- Database
- OrientalUnity
- Thymeleaf
- Scheduler
- Enum
- NaverCloudPlatform
- spring
- 회고
- React
- spring boot
- mybatis
- AssertJ
- F-Lab
- 네이버 클라우드
- NooBLoL
- NCP
- Pinpoint
- Naver Cloud
- junit
- papago
- ncloud
- 에프랩
- Today
- Total
DevJong12
Is Null, Not Null 왜 사용할까요? 당신의 조건문은 Null에 안전한가요? 본문
아티클 주제
우리가 데이터를 대조해서 조회를 할 때 !=, =, like, not like, is Null, Null 다음과 같은 연산자를 많이 사용한다.
해당 포스트는 해당 연산자중에서 !=, not like 와 관련한 내용이다.
해당 문제는 처음 겪은건 Oracle이지만, Maria, Mysql도 문제는 동일하다
이슈내용 전 환경 설명
당시 재직중이던 회사에서 나는 유지보수 업무를 하고 있었다.
고객사가 여러곳이었다보니 다양한 DB벤더를 접할 수 있었는데, 이슈가 발생한 고객사의 DB Vendor는 Oralcle을 활용중이었다.
해당 아티클은 연산자의 문제답게 일단 컬럼에 대해서 설명을 해야 한다.
문제가 발생한 테이블은 아래의 구조를 가지고있다고 가정해보며, 아래의 테이블에서 status컬럼 null able하게 들어가는 것을 기억하면된다.
이슈내용
당시 재직중이던 회사에서 이슈가 발생한 내용은 status컬럼이
여기에서 찾아야 하는 내용은 status != 'PROCESS'로, PROCESS가 아닌 모든 내용을 찾고있는 기능이었다.
그리고 !=를 진행 할 때 null인 항목에 대해서도 가져오는 기능이었으나, 'PROCESS'와 null을 모두 제외한 나머지 ROW들만 가져오는 이슈였다.
이슈 구현
다음과 같은 Table을 만들고, 데이터를 넣었다 가정하자.
DRAFT, REDRAFT, RETURN, END가 각각 1건씩, null이 2건, WRITING이 3건, PROCESS가 4건을 삽입하였다.
이후 아래의 2개의 쿼리를 실행해보겠다.
아래의 스크린샷은 실행한 결과가 출력된 모습이며, 왼쪽이 조건문이 없고, 오른쪽이 조건문이 있는 경우이다.
입력한 모든 데이터는 13건이었으며 PROCESS는 총 4건이었고 null은 총 2건이었다.
우측에서 모두 조회된 데이터는 13건에서 6건이 제외되고 7건이 발생한 모습이다.
이슈 발생 원인
이유는 검색 결과에 애초애 null은 연산자 검색을 진행할 때 해당사항에 들어가지가 않음.
✅ 과거에 위와같이 기록하였으나, 이후 추가적으로 수정을 진행하면서 알게 된내용
= 'PROCESS', !='PROCESS'라는 조건문을 진행할 때 null이 들어가있는 경우에는 =는 항상 False, !=는 항상 True를 반환한다 한다.
코드 디버깅과정으로 이해하면 편할 것 같은데, 해당 ROW를 조회 할 때 컬럼값을 가져와서
null == 'PROCESS', null != 'PROCESS' 다음과 같은 공식이 만들어 지는 것이다.
이러면 프로그래밍에서 당연한 결과라는 생각이 들었다 'PROCESS'라는 값이 실제 존재하니까 ==null 에서는 False가 반환되는거고, 'PROCESS'는 값이 있으니까 !=null에서는 당연히 True가 반환되는게 정상적인 이치라는 생각을 하게 되었다.
해결 방법
검색결과에서 Null에 안전한 조건문을 작성하면 되며, 아래처럼 변경을 하면 된다.
안전한 방법은 다음의 경우였다
- 요구사항에 있던 null을 포함하는 구문을 추가하는것
- null인 경우 다른 값으로 치환해서 조건문을 태우는것
피드백 내역
- 발생원인부분에서 ==null이 true, false로 반환된다는 것이 오류라는 피드백을 받았다.
확실히 해당 부분에 대해서 듣고서 NULL에 대해서 다시 알아봤다. 작성당시에 나는 Java의 디버깅을 기준으로 생각해봤었다.
Java기준으로는 해당 경우가 맞게되기떄문이다. "PROCESS" == null의 결과는 True, 같은 공식으로.. 하지만 DB기준에서는 이 공식이 틀렸고 반환값이 그냥 Null이 되는것..
해당 부분에 대해서 피드백을 받고 알아본 결과 Null은 'DB내의 데이터 값이 존재하지 않는 것을 지시하는 데 사용되는 특별한 표시어' 라고 한다. True도 False도 아닌 Null이라는 그냥 Null이라는것...
>Null에 대해서 많이 참고한 링크 Null에 대해 자세히 보고싶으면 해당 포스트를 읽어 보는것도 좋을 듯하다.
아티클을 작성하면서 느낀 점
옛날에 멘토링을 진행할 때 Null에 안전하게 코드를 작성하는 이유를 생각해보라고 코멘트를 받은 적이 있었다.
해당 문제를 이번에 수정을 하면서 경험하게 들었던 생각이 과거의 코멘트를 받았던 내용이 문득 떠올랐다.
왜 Null에 안전한 개발을 해야할지를 다시금 생각해 볼 수 있었던 문제였다.
22. 05. 16 : 작성
23. 05. 04 : 글의 의미를 조금더 전달하기 쉽게 수정
- 집을 나오면서 이동하는 동안 해당 글의 유입이 발생했다. 그래서 우연히 다시 글을 읽게 되어서 천천히 글을 보고 있었는데 보면서 들었던 생각이 이게 무슨말이지? 라는 생각을 하게 되었다. 조금더 글을 이해하기 쉽게 만들자고 생각하여 수정작업을 진행했다.
- FB에서 받은 첫 피드백에 대한 내용을 추가했다.
- SQL문에서 AND를 사용해버렸다.....