인덱스를 설계할 때 NULL 값을 고려해야 합니다.
데이터베이스에서 NULL 값은 '값이 없음'을 의미합니다.
만약 인덱스에 NULL 값을 포함시키지 않으면, NULL 값을 가진 행을 찾을 때마다 전체 테이블을 스캔해야 하므로 검색 효율성이 떨어집니다.
또한 데이터의 일관성을 유지하는데 문제가 될 수 있습니다.
예를 들어, NULL 값을 가지고 있는 행에 대해서만 작업을 수행하려고 할 때, 해당 행이 인덱스에 포함되지 않아 예상치 못한 결과를 가져올 수 있습니다.
NULL은 값이 없음을 의미하기 때문에, 일반적인 비교 연산자(=, <, > 등)를 사용하면 예상치 못한 결과가 나올 수 있습니다. 따라서 NULL 값을 검사할 때는 IS NULL 또는 IS NOT NULL을 사용해야 합니다.
그러나 NULL 값을 인덱스에 포함시키는 것이 항상 좋은 것은 아닙니다. NULL 값이 많은 경우 인덱스의 크기가 커지고, 디스크 공간이 비효율적으로 사용될 수 있습니다.
따라서 인덱스를 설계할 때는 NULL 값의 비율과 조회 패턴 등을 고려하여 결정해야 합니다.
NULL은 컬럼의 값을 모를 때 사용하는 마커(표시)로 값이 존재하지 않거나 값이 분명하지 않음을 나타낸다.
NULL이 들어간 컬럼값은 실제로도 존재하지 않으며 NULL은 값조차 없다. 어디까지나 마커다.
공집합과 NULL은 다르다. 공집합은 요소가 0개인 집합이며 존재하지 않는 집합인 NULL과 다르다.
SQL에서 NULL인지 아닌지에 대한 판단은 IS NULL or IS NOT NULL로 한다. NULL은 값이 아니라서 값처럼 비교할 수 없다.
수치 연산뿐만 아니라 문자열의 조작도 마찬가지다.
비교 연산도 마찬가지로 NULL이다.
SELECT CONCAT('ABC', NULL) # NULL
SELECT CONCAT('ABC', NULL) LIKE 'ABC%' # NULL

컬럼이 NULL이 되는 것을 의식하지 않고 특별한 조치를 하지 않으면 WHERE 절에서 NULL과의 비교가 이뤄진다. SELECT가 행을 반환하는 것은 WHERE 절의 조건이 TRUE가 됐을 때뿐이다.
NULL은 조건에 맞지 않다고 판단되어 행을 가져오지 않는다.
- 인덱스에 NULL 값 허용 - (기본키는 NULL 허용 X)
- NULL 값 끼리 동일하게 판단 X
- 빈 문자열 NULL 변환 X
인덱스를 만들 때 모든 널 값이 동일하지 않게 처리하기 때문에 널 값이 있는 컬럼에 유일 인덱스를 만들 수 있습니다. 또한 이 컬럼을 포함한 여러 개의 로우도 저장할 수 있습니다.
하지만 MySQL은 인덱스에 NULL 값을 허용하기 때문에 제거하는 옵션이 없습니다. IS NULL과 IS NOT NULL를 사용해 인덱스가 있으면 사용합니다. 또한 빈 문자열은 NULL로 변환하지 않고 길이는 0인 문자열로 처리합니다.
NULL 값을 가진 행을 빠르게 검색할 수 있게 해주는 장점이 있습니다. 그러나 NULL 값이 많은 경우 인덱스의 크기가 커져서 디스크 공간이 비효율적으로 사용될 수 있습니다.
- 인덱스에 NULL 값 허용 X - (기본키는 NULL 허용 X)
- 하지만 복합키에 NULL이 아닌 값이 하나라도 있으면 인덱스로 만들 수 있다.
- NULL 값 끼리 동일하게 판단 X
- 빈 문자열 NULL 변환 O
NULL 값을 가진 행은 인덱스에 포함되지 않기 때문에, 이러한 행을 찾기 위해서는 테이블 전체를 스캔해야 합니다.
오라클은 특이하게 인덱스에 NULL을 허용하지 않지만, 복합키인 경우 값이 하나라도 NULL이 아니면 인덱스로 만들 수 있습니다. 즉 하나의 상수 값을 포함하거나 NULL을 처리 할 수 있는 NVL(), COALESCE()함수를 통해 인덱스를 사용하도록 강제할 수 있습니다. (함수 기반 인덱스)
또한 빈 문자열과 NULL을 동일하게 취급합니다.
- 인덱스에 NULL 값 허용 O - (기본키는 NULL 허용 X)
- NULL 값 끼리 동일하게 판단 O - (Unique Column에는 NULL값 하나만 지정 가능)
- 빈 문자열 NULL 변환 X
인덱스에서 널 값을 제외하려면 필터링된 인덱스를 만들어야 합니다.
CREATE INDEX StudentNumber_IDX
ON Students (Number)
WHERE Number IS NOT NULL;
IS NULL 조건을 통해 Index를 필터링 시킵니다. 또한 빈 문자열은 NULL처리를 하지 않기 때문에 인덱스를 만들 수 있습니다.
인덱스로 만들 컬럼에 널 값을 허용할지 고려해야한다.
널 값을 검색하고 싶은데 컬럼 값의 대다수가 NULL이라면, 이 컬럼은 인덱스로 만들지 않는 것이 낫다.
컬럼에 있는 값을 좀 더 빠르게 검색하고 싶은데 값의 대다수가 NULL이라면, 널 값을 제외하고 인덱스를 만드는 것이 좋다.
- 인덱스에 NULL 값 허용 O - (기본키는 NULL 허용 X)
- NULL 값 끼리 동일하게 판단 X
- 빈 문자열 NULL 변환 X
PostgreSQL은 인덱스에 널 값을 포함할 수 있지만 WHERE 절을 통해 조건을 정의하여 제외합니다.
CREATE INDEX StudentNumber_IDX
ON Students (Number)
WHERE Number IS NOT NULL;
또한 길이가 0인 문자열을 NULL로 변환하지 않으며 빈 문자열과 NULL을 다른 값으로 인식합니다.
https://poododang.tistory.com/entry/effective-sql-10
https://www.sunny-son.space/MySQL/RDBMstart07/