NULL과의 비교 연산(=, <>) 결과
데이터 세계의 투명 인간 NULL을 이해하는 법
데이터베이스나 프로그래밍을 처음 시작하는 사람들이 가장 당혹스러워하는 순간 중 하나는 바로 NULL 값과의 만남입니다. 수학적 사고방식에 익숙한 우리는 보통 어떤 값이 ‘없다’고 하면 0이라고 생각하거나, 아무것도 없으니 서로 같다고 판단하기 쉽습니다. 하지만 컴퓨터의 세계, 특히 데이터베이스 시스템에서 NULL은 단순한 ‘0’이나 ‘빈 문자열’이 아닙니다. NULL은 ‘알 수 없음(Unknown)’ 혹은 ‘값이 존재하지 않음’을 의미하는 아주 특별한 상태입니다. 이 때문에 NULL과 일반적인 비교 연산자를 사용하면 예상치 못한 결과를 얻게 됩니다.
NULL은 왜 0이나 공백과 다른가요
많은 초보 개발자가 흔히 저지르는 실수는 NULL을 0이나 빈 공간으로 취급하는 것입니다. 이를 명확히 구분하기 위해 다음의 비유를 들어보겠습니다.
- 숫자 0: 잔액이 0원인 통장입니다. 돈이 없다는 사실이 명확합니다.
- 빈 문자열: 아무것도 쓰여 있지 않은 깨끗한 공책입니다. 공책은 존재하며 그 안에 내용이 없음을 확인했습니다.
- NULL: 아예 존재하지 않는 통장 혹은 내용물을 알 수 없는 봉인된 상자입니다. 이 통장에 잔액이 얼마인지, 이 상자 안에 무엇이 들어있는지 우리는 전혀 알 수 없습니다.
이처럼 NULL은 ‘정보의 부재’ 그 자체를 의미하기 때문에, 수학적인 논리 연산이 적용되지 않습니다. 0은 0과 같지만, NULL은 NULL과 같다고 말할 수조차 없는 상태인 것입니다.
비교 연산자와 NULL이 만나면 발생하는 일
데이터베이스에서 일반적인 비교 연산자(=, !=, <>, >, <)를 사용해 NULL을 조회하려고 하면, 대부분의 경우 결과는 '거짓(False)'도 아니고 '참(True)'도 아닌 '알 수 없음(Unknown)'을 반환합니다. SQL 표준에서 NULL과의 비교는 항상 Unknown을 반환하며, 이는 결과적으로 해당 조건이 참이 아니라고 판단되어 쿼리 결과에 포함되지 않게 만듭니다.
흔한 오해와 진실
- 오해: WHERE column = NULL 이라고 쓰면 NULL인 데이터를 찾을 수 있다.
- 진실: 위 쿼리는 아무런 결과도 반환하지 않습니다. NULL은 값 자체가 아니기에 ‘같다’라는 개념을 적용할 수 없습니다.
- 오해: WHERE column != NULL 이라고 쓰면 NULL이 아닌 데이터를 모두 찾을 수 있다.
- 진실: 이 역시 아무것도 반환하지 않습니다. NULL이 아닌 데이터를 찾으려면 별도의 연산자를 사용해야 합니다.
NULL을 안전하게 다루는 실전 기술
데이터베이스에서 NULL을 제대로 다루기 위해서는 표준 연산자 대신 특별히 설계된 함수와 연산자를 사용해야 합니다. 다음은 실무에서 가장 자주 사용되는 방법들입니다.
IS NULL과 IS NOT NULL 활용하기
가장 기본적이면서도 확실한 방법입니다. 데이터가 NULL인지 아닌지를 명확하게 판별할 수 있습니다.
- SELECT FROM users WHERE email IS NULL; (이메일 정보가 없는 사용자 찾기)
- SELECT FROM users WHERE email IS NOT NULL; (이메일 정보가 등록된 사용자 찾기)
COALESCE 함수로 NULL 대체하기
NULL이 발생할 가능성이 있는 데이터를 조회할 때, NULL 대신 기본값을 보여주고 싶다면 COALESCE 함수를 사용하는 것이 좋습니다. 이 함수는 나열된 인자 중 NULL이 아닌 첫 번째 값을 반환합니다.
- SELECT name, COALESCE(phone, ‘연락처 없음’) FROM users;
이 쿼리는 전화번호가 NULL인 경우 ‘연락처 없음’이라는 문자열을 대신 출력하여 사용자에게 친절한 데이터를 제공합니다.
NULLIF 함수로 특정 값 무효화하기
반대로 특정 값이 어떤 조건과 일치할 때 이를 NULL로 바꾸고 싶다면 NULLIF를 사용합니다. 예를 들어, 나이가 0으로 잘못 입력된 데이터를 NULL로 처리하여 평균 계산에서 제외하고 싶을 때 유용합니다.
- SELECT AVG(NULLIF(age, 0)) FROM users;
데이터 분석과 개발 시 주의사항
NULL은 단순히 쿼리에서만 문제를 일으키는 것이 아닙니다. 애플리케이션 로직을 작성할 때도 NULL 체크를 간과하면 런타임 오류(NullPointerException 등)의 주범이 됩니다.
전문가의 조언
첫째, 데이터베이스 설계 단계에서 가능한 한 NOT NULL 제약 조건을 활용하세요. 데이터의 성격상 반드시 값이 있어야 하는 필드라면 처음부터 NULL이 들어오지 못하게 막는 것이 가장 비용 효율적인 해결책입니다.
둘째, 통계 쿼리를 작성할 때 주의가 필요합니다. 집계 함수인 SUM, AVG, COUNT 등은 NULL 값을 계산에서 제외합니다. 예를 들어, 5명 중 2명의 점수가 NULL이라면 AVG는 나머지 3명의 점수만 합산하여 나눕니다. 이 점을 인지하지 못하면 전체 평균이 왜곡되었다고 오해할 수 있습니다.
셋째, 외부 시스템과 데이터를 주고받을 때 NULL 처리를 명시하세요. API 통신 시 NULL을 빈 문자열로 보낼지, 아니면 필드 자체를 생략할지에 대한 합의가 없다면 데이터를 받는 쪽에서 치명적인 오류가 발생할 수 있습니다.
자주 묻는 질문과 답변
Q: NULL과 공백(빈 문자열)은 데이터베이스에서 똑같이 취급되나요?
A: 아닙니다. 대부분의 RDBMS(MySQL, PostgreSQL, Oracle 등)에서 NULL과 빈 문자열은 엄격하게 구분됩니다. 다만 Oracle의 경우 빈 문자열을 NULL로 간주하는 독특한 특성이 있으니 사용하는 데이터베이스의 매뉴얼을 반드시 확인해야 합니다.
Q: ORDER BY를 사용할 때 NULL은 어디에 위치하나요?
A: NULL은 일반적인 값보다 ‘크다’고 간주되는 경우가 많아 오름차순 정렬 시 가장 마지막에 위치하는 경우가 많습니다. 이를 제어하기 위해 NULLS FIRST 또는 NULLS LAST 옵션을 사용하여 위치를 강제로 지정할 수 있습니다.
Q: 성능 측면에서 IS NULL 연산은 느린가요?
A: 과거에는 NULL 처리가 인덱스를 타지 않는 경우가 많았으나, 최근의 현대적인 데이터베이스 엔진은 IS NULL 검색을 위한 인덱스 최적화가 잘 되어 있습니다. 하지만 대규모 데이터셋에서는 인덱스 설계 시 NULL의 분포를 고려하는 것이 성능 향상에 큰 도움이 됩니다.
NULL을 다루는 효율적인 전략
NULL과 관련된 문제를 최소화하는 것은 고품질 소프트웨어를 만드는 핵심 역량입니다. 다음은 실무에서 적용할 수 있는 몇 가지 가이드라인입니다.
- 기본값 설정: 비즈니스 로직상 NULL이 필요 없다면 기본값(Default Value)을 설정하여 데이터의 일관성을 유지하세요.
- 방어적 프로그래밍: 데이터를 처리하는 코드 앞단에서 NULL 체크를 하는 습관을 들이세요. 언어별로 제공하는 옵셔널(Optional) 타입이나 널 병합 연산자(??)를 적극 활용하는 것이 좋습니다.
- 가독성 우선: 복잡한 쿼리에서 NULL 비교를 여러 번 수행해야 한다면, CASE 문을 사용하여 로직을 명확하게 분리하세요.
결론적으로 NULL은 데이터의 ‘알 수 없음’을 표현하는 강력한 도구이지만, 이를 다루는 규칙을 모르면 혼란을 초래하는 복병이 됩니다. 비교 연산자(=) 대신 IS NULL을 사용하고, 데이터의 성격을 정확히 파악하여 COALESCE나 NULLIF 같은 함수를 적재적소에 활용한다면, 여러분은 데이터의 투명 인간인 NULL을 완벽하게 통제할 수 있게 될 것입니다. 데이터의 공백을 이해하는 것, 그것이 바로 데이터 전문가로 나아가는 첫걸음입니다.
ace


댓글 0
첫 댓글을 남겨보세요.