데이터베이스

[MySQL & PostgreSQL] Null 값을 안전하게 비교하기

후뿡이 2024. 12. 14. 14:02

1. 문제 상황


PostgreSQL 에서 nullable 한 column 의 값이 변경이 되면 History 데이터를 쌓도록 Trigger 를 만들고 있었습니다.

if OLD.purpose <> NEW.purpose 인 경우 Trigger 가 실행 되도록 했다.

 

그런데 purpose 값을 바꿔도 History 데이터가 생성이 되지 않았습니다.

purpose 가 아닌 다른 값을 변경하는 경우에는 정상적으로 Trigger 가 동작하는 것으로 봐서는

Trigger 가 적용이 안 된 문제는 아닌 것 같은데 ...

 

2. 문제 원인


문제의 원인을 알아냈습니다.

 

설명하기 전에 아래의 쿼리의 결과를 예상해봅시다 ! 

select 
	null =  null,
	null <> null,
	null  = 1,
	null <> 1,
	   1  = 1,
	   1 <> 1;

 

 

 

답은 아래와 같습니다.

  1. null
  2. null
  3. null
  4. null
  5. true
  6. false

 

문제 원인은 MySQL 과 PostgreSQL 에서 모두 Null 과 equal ( 동등 비교 ) 를 하면 전부 null 값이 나오는 것에 있었습니다.

 

 

3. MySQL 의 Null-Safe Equal Operator


MySQL 에서는 위와 같은 문제를 해결하기 위해 null safe equal operator <=> 를 제공합니다. 공식문서

<=> 동등 연산자를 사용하면 Null 값과 같은지 다른지도 비교가 가능해 집니다.

 

-- MySQL

select 
	null <=>  null, -- TRUE
	null <=> 1;     -- FALSE

 

4. PostgreSQL 의 Null-Safe Equal Operator


postgresql 은 MySQL 의 <=> 은 제공하지 않지만 다른 기능을 제공합니다.

IS NOT DISTINCT FROM 이라는 기능입니다. ( 반대 의밀로 IS DISTINCT FROM 도 사용이 가능합니다 ) 

의미 그대로 ~로 부터 구별되지 않는다 => 즉 같다 ! 라는 의미로 사용됩니다.

-- PostgreSQL

SELECT 
	NULL IS NOT DISTINCT FROM NULL, -- TRUE
	NULL IS NOT DISTINCT FROM 1,    -- FALSE
	1    IS NOT DISTINCT FROM 2,    -- FALSE
	1    IS NOT DISTINCT FROM 1;    -- TRUE