맨위로가기

Null (SQL)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

NULL (SQL)은 SQL에서 "값 없음" 또는 "알 수 없는 값"을 나타내는 특수한 마커로, 1975년 처음 언급되었으며 1986년 SQL 표준에 채택되었다. NULL은 산술 연산, 문자열 연결 등에서 예상치 못한 결과를 초래하며, 3가지 논리(참, 거짓, 알 수 없음)를 사용하여 처리된다. NULL은 SQL의 WHERE 절, 조인, CASE 표현식, 집계 함수 등 다양한 구문에서 특별한 방식으로 처리되며, IS NULL 및 IS NOT NULL과 같은 특수 연산자를 사용하여 명시적으로 처리해야 한다. NULL의 구현은 논란의 대상이 되었으며, 다양한 실수와 비판, 그리고 폐쇄 세계 가정을 위반한다는 주장이 제기되었다.

더 읽어볼만한 페이지

  • SQL 키워드 - TRUNCATE (SQL)
    TRUNCATE는 SQL에서 테이블 내의 모든 데이터를 빠르게 삭제하는 명령어로, 외래 키 제약 조건 무시, 테이블 잠금 방식, 트랜잭션 처리 방식 등 DELETE 명령어와 차이를 보이며, WHERE 절을 사용할 수 없어 테이블의 모든 행을 삭제하고, 일부 데이터베이스 시스템에서는 롤백이 불가능할 수 있다.
  • SQL 키워드 - ALTER (SQL)
    ALTER (SQL)은 SQL에서 데이터베이스 객체의 구조를 변경하는 명령문으로, 테이블에 컬럼을 추가/삭제하거나 이름을 변경하는 데 사용되며, 데이터베이스 시스템에 따라 구문과 사용법이 다르다.
Null (SQL)
데이터베이스
종류데이터베이스 모델의 개념
의미값이 존재하지 않거나, 비어 있거나, 적용할 수 없음을 나타내는 특수한 마커
SQL에서의 NULL
특징SQL에서는 NULL은 '알 수 없는 값'을 의미하며, 다른 데이터베이스와는 다른 의미를 가질 수 있음
NULL은 0이나 빈 문자열과는 다름
NULL은 어떠한 데이터 타입도 가질 수 있음
비교NULL과의 비교는 IS NULL 또는 IS NOT NULL 연산자를 사용해야 함 (= 또는 != 연산자 사용 불가)
NULL = NULL은 거짓(false)으로 평가됨
정렬정렬 시 NULL 값의 위치는 데이터베이스 시스템에 따라 다름 (일반적으로는 가장 먼저 또는 가장 나중에 정렬됨)
계산NULL 값과의 계산 결과는 항상 NULL이 됨
제약 조건NOT NULL 제약 조건을 사용하여 해당 열에 NULL 값이 들어가지 않도록 할 수 있음
의미론데이터베이스마다 NULL의 의미론이 다를 수 있으므로 주의해야 함
활용 예시
예시연락처 정보가 없는 고객의 경우, '전화번호' 열에 NULL 값을 저장할 수 있음

2. 역사

E. F. 콧(E. F. Codd)은 1975년 《''FDT Bulletin of ACM-SIGMOD''》 논문에서 널(NULL)을 빠진 데이터를 나타내는 수단으로 언급했다.[38] 1979년 《''ACM 데이터베이스 시스템 트랜잭션''》 논문에서 콧은 관계 모델/태즈매니아를 소개하고, 널의 의미론과 3가 논리(참, 거짓, 미지)를 이용한 비교 연산을 구체화하였다.[4] 데이터베이스 이론계에서는 1975년과 1979년 콧의 제안을 ‘콧의 테이블’로 언급한다. 콧은 이후 1985년 《컴퓨터 월드》 기고문에서 모든 RDBMS가 빠진 데이터를 나타내기 위해 Null을 지원해야 한다고 주장했다.[1][2]

1986년 SQL 표준은 IBM System R 프로토타입을 기반으로 콧의 제안을 채택했다.[3] 돈 챔벌린은 널을 SQL의 가장 논쟁적인 기능 중 하나로 인식하면서도, 실용적인 측면을 들어 널 설계를 옹호했다. 그는 널이 누락된 정보에 대한 시스템 지원의 가장 저렴한 형태이며, 프로그래머가 많은 중복된 애플리케이션 수준 검사를 수행하지 않아도 된다고 주장했다.( 반술어 문제 참조) 동시에 데이터베이스 디자이너가 원할 경우 널을 사용하지 않을 수 있는 옵션을 제공했다. 챔벌린은 또한 일부 누락된 값 기능을 제공하는 것 외에도 널에 대한 실질적인 경험이 특정 그룹화 구성 및 외부 조인과 같이 널에 의존하는 다른 언어 기능으로 이어졌다고 주장했다.

코드는 1990년 저서 ''데이터베이스 관리를 위한 관계형 모델, 버전 2''에서 SQL 표준의 단일 널(Null)은 부적절하며, 두 개의 별도 널(Null) 타입 마커("누락되었지만 적용 가능", "누락되었지만 적용 불가능")로 대체해야 한다고 주장했다.[33] 코드의 권고는 SQL 논리 시스템이 4진 논리 시스템을 수용하도록 확장해야 함을 의미했다. 이러한 복잡성 때문에 서로 다른 정의를 가진 여러 널(Null)에 대한 아이디어는 데이터베이스 실무자 영역에서 널리 받아들여지지 않았다.

3. NULL의 전파

NULL은 산술 연산이나 문자열 연결 등에서 연산 결과로 전파될 수 있다. 즉, NULL과의 산술 연산 결과는 대부분 NULL이며, 문자열 연결 연산에서도 피연산자 중 하나가 NULL이면 결과는 NULL이다. (단, 오라클 RDBMS는 예외)[7]

E. F. 코드는 1975년 ''ACM-SIGMOD''의 ''FDT Bulletin'' 논문에서 관계형 모델에서 누락된 데이터를 표현하는 방법으로 널(Null)을 언급했다.[4] 그는 1979년 ''ACM 데이터베이스 시스템 트랜잭션'' 논문에서 널과의 비교 시 삼진 논리를 사용하여 산술 연산 및 비교에서 널이 전파되는 세부 사항을 설명했다.[4]

Null은 데이터 값이 아닌, 값이 없음을 나타내는 표시이므로 Null에 수학 연산자를 사용하면 알 수 없는 결과, 즉 Null이 나온다.[5]

3. 1. 산술 연산

널은 데이터 값이 아니라, 미지의 값에 대한 표시일 뿐이기 때문에, Null에 수학적 연산을 하는 것은 미지의 값으로 나타난다.[41] 10을 Null에 곱하면 결과값은 Null이 된다.[41]

```sql

10 * NULL -- 결과는 NULL

```

이는 예기치 않은 결과를 야기한다. 예를 들어, 널을 0으로 나누려 한다면, 플랫폼은 ‘0으로 나눈’ 예상된 데이터 예외값을 던지는 대신, 널 값을 반환한다.[41] 비록 이러한 행위가 ISO SQL 표준으로 정의되어 있지는 않지만, 많은 DBMS 벤더들이 이러한 연산을 유사하게 다룬다. 예를 들어, 오라클, PostgreSQL, MySQL 서버, 마이크로소프트 SQL 서버 플랫폼은 모두 널 값을 아래와 같이 반환한다.[41][5]

```sql

NULL / 0

3. 2. 문자열 연결

SQL에서 흔히 쓰이는 문자열 연결 연산은 피연산자 중 하나가 Null 값이면 결과도 Null 값이다.[42][6]

예:

```sql

'Fish ' || NULL || 'Chips' -- 결과는 NULL

```

이는 모든 데이터베이스 구현에 해당되는 것은 아니다. 예를 들어, 오라클 RDBMS에서는 NULL과 빈 문자열을 동일하게 간주하므로 'Fish ' || NULL || 'Chips'의 결과는 'Fish Chips'가 된다.[7]

4. NULL과 3가 논리 (3VL)

NULL은 데이터 도메인의 일부가 아니므로 값으로 간주되지 않지만, 값의 부재를 나타내는 마커 역할을 한다. 이러한 이유로 NULL과의 비교는 '참'(True)이나 '거짓'(False)이 아닌, 항상 제3의 논리값인 '알 수 없음'(Unknown)으로 나타난다.[43]

예를 들어, 다음과 같이 10과 Null을 비교하면 결과는 Unknown이 된다.

```sql

SELECT 10 = NULL -- 결과는 Unknown

```

그러나 Null 값이 연산 결과에 영향을 주지 않는 경우, Null에 대한 연산은 값을 반환할 수 있다. 예를 들어:

```sql

SELECT NULL OR TRUE -- 결과는 True

```

위의 예시에서 OR 연산의 왼쪽 값이 알 수 없음(Unknown)이라는 사실은 결과에 영향을 미치지 않는다. OR 연산의 결과는 왼쪽 값에 관계없이 항상 참이기 때문이다.

E. F. 코드는 1975년 ACM-SIGMOD의 FDT Bulletin 논문에서 관계형 모델에서 누락된 데이터를 표현하는 방법으로 널을 언급했다. SQL에서 채택된 널의 의미론과 관련하여 가장 일반적으로 인용되는 코드의 논문은 1979년 ACM 데이터베이스 시스템 트랜잭션에 실린 논문이다. 이 논문에서 그는 관계형 모델/태즈메이니아를 소개했지만, 다른 제안들은 대부분 알려지지 않았다. 그의 1979년 논문의 2.3절에서는 널과의 비교 시 삼진 논리를 사용하여 산술 연산 및 비교에서 널의 전파에 대한 세부 사항을 설명하고, 다른 집합 연산에 대한 널의 처리 방식도 자세히 설명한다(후자의 문제는 오늘날에도 여전히 논란의 대상이다).[4] 코드는 이후 1985년 ''컴퓨터 월드'' 잡지에 게재된 2부작 기사에서 모든 RDBMS가 누락된 데이터를 나타내기 위해 널을 지원해야 한다고 다시 한 번 강조했다.[1][2]

1986년 SQL 표준은 IBM System R에서 구현 프로토타입을 거친 후 코드의 제안을 채택했다. 돈 챔벌린은 널을 SQL의 가장 논란이 많은 기능 중 하나로 인식했지만, 누락된 정보에 대한 시스템 지원의 가장 저렴한 형태였고, 프로그래머가 많은 중복된 애플리케이션 수준 검사를 수행하지 않아도 되도록 해준다(반술어 문제 참조)는 실용적인 주장을 내세우면서 SQL에서 널의 설계를 옹호했다.[3]

SQL은 세 가지 논리적 결과(참, 거짓, 알 수 없음)를 구현하므로, 특수한 삼진 논리(3VL)를 제공해야 한다. SQL 삼진 논리의 규칙은 아래 표와 같다. 여기서 '''p'''와 '''q'''는 논리적 상태를 나타낸다.[9]

pqp OR qp AND qp = q
거짓거짓거짓
알 수 없음알 수 없음알 수 없음
거짓거짓거짓
거짓거짓거짓거짓
거짓알 수 없음알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음
알 수 없음거짓알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음알 수 없음알 수 없음



pNOT p
거짓
거짓
알 수 없음알 수 없음



SQL 표준은 또한 IS NULLIS NOT NULL 술어를 제공하여 데이터가 Null인지 아닌지를 판별한다.[11]

SQL 표준에는 선택적 기능 F571 "진리값 테스트"가 존재하며, 이는 세 개의 논리 단항 연산자를 도입한다. 이 연산자들의 진리표는 다음과 같다.[12]

pp IS TRUEp IS NOT TRUEp IS FALSEp IS NOT FALSEp IS UNKNOWNp IS NOT UNKNOWN
TrueTrueFalseFalseTrueFalseTrue
FalseFalseTrueTrueFalseFalseTrue
Un­knownFalseTrueFalseTrueTrueFalse



F571 기능은 SQL92에 이미 존재했으며,[13] PostgreSQL 등 일부 시스템에서 구현되었다.

IS UNKNOWN을 SQL의 3가 논리의 다른 연산자에 추가하면, SQL의 3가 논리가 기능적으로 완전하게 된다.[14]

4. 1. WHERE 절에서의 영향

NULL은 어떠한 데이터 도메인의 구성원도 아니기 때문에, "값"으로 간주되지 않고 정의되지 않은 값을 나타내는 마커(또는 자리 표시자)로 간주된다.[8] 이 때문에 NULL과의 비교는 참 또는 거짓의 결과를 가질 수 없고, 항상 세 번째 논리적 결과인 알 수 없음(Unknown)이 된다.[8]

SQL의 3치 논리는 데이터 조작 언어(DML)에서 DML 문과 쿼리의 비교 술어에 나타난다. WHERE 절은 술어가 참으로 평가되는 행에 대해서만 DML 문이 작동하도록 한다. 술어가 거짓 또는 알 수 없음으로 평가되는 행은 SELECT 쿼리에 의해 폐기된다. 알 수 없음과 거짓을 동일한 논리적 결과로 해석하는 것은 Null을 처리할 때 발생하는 흔한 오류이다.[9]

```sql

SELECT *

FROM t

WHERE i = NULL;

```

위의 예제 쿼리는 논리적으로 항상 0개의 행을 반환하는데, 이는 ''i'' 열과 Null의 비교가 항상 알 수 없음을 반환하기 때문이다. ''i''가 Null인 행에 대해서도 마찬가지이다. 알 수 없음 결과로 인해 SELECT 문은 모든 행을 즉시 폐기한다. (그러나 실제로 일부 SQL 도구는 Null과의 비교를 사용하여 행을 검색한다.)

Null (SQL)의 작동 방식을 잘못 이해하는 것은 ISO 표준 SQL 문과 실제 데이터베이스 관리 시스템에서 지원하는 특정 SQL 방언 모두에서 SQL 코드의 많은 오류를 발생시키는 원인이다. 이러한 실수는 일반적으로 Null과 0(영) 또는 빈 문자열(SQL에서 `''`로 표시되는 길이가 0인 문자열 값) 사이의 혼동으로 인해 발생한다. 그러나 Null은 SQL 표준에 의해 빈 문자열 및 숫자 값 0과 모두 다르게 정의된다. Null은 값이 없음을 나타내는 반면, 빈 문자열과 숫자 0은 모두 실제 값을 나타낸다.

전형적인 오류는 NULL 키워드와 결합된 등호 연산자 =를 사용하여 Null이 있는 행을 찾으려는 시도이다. SQL 표준에 따르면 이는 잘못된 구문이며 오류 메시지 또는 예외를 발생시켜야 한다. 그러나 대부분의 구현은 구문을 허용하고 이러한 표현식을 UNKNOWN으로 평가한다. 결과적으로 Null이 있는 행이 존재하든 존재하지 않든 상관없이 행이 발견되지 않는다. Null이 있는 행을 검색하는 제안된 방법은 = NULL 대신 술어 IS NULL을 사용하는 것이다.

```sql

SELECT *

FROM sometable

WHERE num = NULL; -- "WHERE num IS NULL"이어야 한다.

```

관련되지만 더 미묘한 예로, WHERE 절 또는 조건문은 열의 값을 상수로 비교할 수 있다. 누락된 값이 해당 필드에 Null이 포함된 경우 상수보다 "작거나 같지 않다"고 잘못 가정하는 경우가 많지만, 실제로 이러한 표현식은 알 수 없음을 반환한다. 다음은 그 예이다.

```sql

SELECT *

FROM sometable

WHERE num <> 1; -- num이 NULL인 행은 반환되지 않는다.

  • - 많은 사용자의 기대와는 다르다.

```

이러한 혼동은 동일성 법칙이 SQL의 논리에서 제한되기 때문에 발생한다. NULL 리터럴 또는 UNKNOWN 진리 값을 사용하여 동등성 비교를 처리할 때 SQL은 항상 표현식의 결과로 UNKNOWN을 반환한다. 이는 부분 동치 관계이며 SQL을 ''비반사적 논리''의 예로 만든다.[32]

4. 2. 배제된 제4법칙 (Law of the excluded fourth)

SQL의 삼진 논리(3VL)에서 ''p'' OR NOT ''p''는 모든 ''p''에 대해 참이 아니다. ''p''가 알 수 없음(Unknown)이면, ''p'' OR NOT ''p''는 알 수 없음으로 평가된다.[43] 따라서 WHERE 절에서 고전적인 이진 논리의 배중률을 적용하는 것은 흑백 논리 오류이다.

예를 들어, 다음 쿼리는

```sql

SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 );

```

x 열에 Null이 포함되어 있다면, 아래의 SQL문과 동일하지 않다.

```sql

SELECT * FROM stuff;

```

위의 두 번째 쿼리는 첫 번째 쿼리가 반환하지 않는 행, 즉 x가 Null인 모든 행을 반환한다. 고전적인 이진 논리에서 배중률은 WHERE 절의 술어 단순화를 허용하며, 사실상 제거를 가능하게 한다.

두 번째 쿼리는 실제로 다음과 동일하다.

```sql

SELECT * FROM stuff;

  • - (3VL 때문에) 다음과 동일합니다.

SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ) OR x IS NULL;

```

따라서 SQL에서 첫 번째 문을 올바르게 단순화하려면 x가 null이 아닌 모든 행을 반환해야 한다.

```sql

SELECT * FROM stuff WHERE x IS NOT NULL;

```

SQL의 WHERE 절에 대해 항진명제와 유사하게 ''p'' OR (NOT ''p'') OR (''p'' IS UNKNOWN)은 모든 술어 ''p''에 대해 참이다. 이를 배타적 넷째 법칙이라고 부른다.

5. NULL 관련 술어 및 연산자

NULL은 어떠한 데이터 도메인의 구성원도 아니기 때문에, "값"으로 간주되지 않고 정의되지 않은 값을 나타내는 마커(또는 자리 표시자)로 간주된다.[8] 이 때문에 NULL과의 비교는 참 또는 거짓의 결과를 가질 수 없고, 항상 세 번째 논리적 결과인 알 수 없음(Unknown)이 된다.[8] 예를 들어, 값 10과 NULL을 비교하는 다음 식의 논리적 결과는 알 수 없음이다.



SELECT 10 = NULL -- 결과는 알 수 없음



그러나 NULL에 대한 특정 연산은 부재하는 값이 연산의 결과와 관련이 없는 경우 값을 반환할 수 있다. 다음 예를 보자.



SELECT NULL OR TRUE -- 결과는 참



이 경우 OR 연산의 왼쪽에 있는 값을 알 수 없다는 사실은 관련이 없다. 왜냐하면 OR 연산의 결과는 왼쪽 값에 관계없이 참이 될 것이기 때문이다.

SQL은 세 가지 논리적 결과를 구현하므로, SQL 구현은 특수화된 삼진 논리(3VL)를 제공해야 한다. SQL 삼진 논리를 지배하는 규칙은 아래 표에 나와 있다(''''p'''와 '''q'''는 논리적 상태를 나타낸다).[9] SQL이 AND, OR 및 NOT에 사용하는 진리표는 Kleene 및 Łukasiewicz 삼진 논리의 공통적인 부분에 해당한다(그러나 함축의 정의는 다르다. SQL은 그러한 연산을 정의하지 않는다).[10]

pqp OR qp AND qp = q
거짓거짓거짓
알 수 없음알 수 없음알 수 없음
거짓거짓거짓
거짓거짓거짓거짓
거짓알 수 없음알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음
알 수 없음거짓알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음알 수 없음알 수 없음



pNOT p
거짓
거짓
알 수 없음알 수 없음



SQL의 WHERE 절에 대해 배중률과 유사한 항진명제를 작성할 수 있다. `IS UNKNOWN` 연산자가 있다고 가정하면, ''p'' OR (NOT ''p'') OR (''p'' IS UNKNOWN)은 모든 술어 ''p''에 대해 참이다. 논리학자들 사이에서 이것은 배타적 넷째 법칙이라고 불린다.

5. 1. NULL 특정 비교 술어

SQL 표준은 `IS NULL`과 `IS NOT NULL`이라는 두 가지 NULL 특정 비교 술어를 제공한다. 이 술어들은 데이터가 NULL인지 아닌지를 확인한다.[11]

5. 2. 진리값 테스트 (선택적 기능 F571)

SQL 표준은 선택적 기능 F571 "진리값 테스트"를 통해 `IS TRUE`, `IS NOT TRUE`, `IS FALSE`, `IS NOT FALSE`, `IS UNKNOWN`, `IS NOT UNKNOWN` 연산자를 제공한다.[12] 이러한 연산자들은 후위 표기법을 사용한다. `IS UNKNOWN` 연산자를 추가함으로써 SQL의 삼진 논리(3VL)는 기능적으로 완전하게 된다.[14] 즉, 논리 연산자 조합을 통해 모든 삼진 논리 함수를 표현할 수 있다.

이 연산자들의 진리표는 다음과 같다.[12]

pp IS TRUEp IS NOT TRUEp IS FALSEp IS NOT FALSEp IS UNKNOWNp IS NOT UNKNOWN
거짓거짓거짓
거짓거짓거짓거짓
알 수 없음거짓거짓거짓



F571 기능은 SQL92에 이미 존재했으며,[13] 1999년 부울 데이터 유형이 표준에 도입되기 훨씬 전부터 있었다. PostgreSQL 등 일부 시스템에서 이 기능을 구현했다.

F571 기능을 지원하지 않는 시스템에서는 `IS UNKNOWN` ''p''를 에뮬레이션하기 위해, 표현식 ''p''를 Unknown으로 만들 수 있는 모든 인수를 찾아 `IS NULL` 또는 기타 NULL 관련 함수로 테스트해야 한다.

6. 다른 구문에서의 NULL 및 미지의 영향

NULL은 어떠한 데이터 도메인의 구성원도 아니기 때문에 "값"으로 간주되지 않고 정의되지 않은 값을 나타내는 마커(또는 자리 표시자)로 간주된다. 이 때문에 NULL과의 비교는 참 또는 거짓의 결과를 가질 수 없고, 항상 세 번째 논리적 결과인 알 수 없음(Unknown)이 된다.[8] 예를 들어, 값 10과 NULL을 비교하는 다음 식의 논리적 결과는 알 수 없음이다.



SELECT 10 = NULL -- 결과는 알 수 없음



그러나 NULL에 대한 특정 연산은 부재하는 값이 연산의 결과와 관련이 없는 경우 값을 반환할 수 있다. 다음 예시를 보자.



SELECT NULL OR TRUE -- 결과는 참



이 경우 OR 연산의 왼쪽에 있는 값을 알 수 없다는 사실은 관련이 없다. 왜냐하면 OR 연산의 결과는 왼쪽 값에 관계없이 참이 될 것이기 때문이다.

SQL은 세 가지 논리적 결과를 구현하므로, SQL 구현은 특수화된 삼진 논리(3VL)를 제공해야 한다. SQL 삼진 논리를 지배하는 규칙은 아래 표에 나와 있다(''''p'''와 '''q'''는 논리적 상태를 나타낸다).[9] SQL이 AND, OR 및 NOT에 사용하는 진리표는 Kleene 및 Łukasiewicz 삼진 논리의 공통적인 조각에 해당한다(그러나, 함축의 정의에서 다르다. SQL은 그러한 연산을 정의하지 않는다).[10]

pqp OR qp AND qp = q
거짓거짓거짓
알 수 없음알 수 없음알 수 없음
거짓거짓거짓
거짓거짓거짓거짓
거짓알 수 없음알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음
알 수 없음거짓알 수 없음거짓알 수 없음
알 수 없음알 수 없음알 수 없음알 수 없음알 수 없음



pNOT p
거짓
거짓
알 수 없음알 수 없음



기본 SQL 비교 연산자는 Null과 비교할 때 항상 Unknown을 반환하므로 SQL 표준은 두 가지 특수한 Null 관련 비교 술어를 제공한다. `IS NULL` 및 `IS NOT NULL` 술어는 (후위 표기법 구문을 사용) 데이터가 Null인지, 아닌지를 테스트한다.[11]

SQL 표준에는 세 개의 추가 논리 단항 연산자(실제로 부정을 포함하면 6개, 구문의 일부임)를 도입하는 선택적 기능 F571 "진리값 테스트"가 포함되어 있으며, 후위 표기법을 사용한다. 다음과 같은 진리표가 있다.[12]

pp IS TRUEp IS NOT TRUEp IS FALSEp IS NOT FALSEp IS UNKNOWNp IS NOT UNKNOWN
TrueTrueFalseFalseTrueFalseTrue
FalseFalseTrueTrueFalseFalseTrue
알 수 없음FalseTrueFalseTrueTrueFalse



F571 기능은 SQL의 부울 데이터 유형의 존재와 직교하며(이 기사 뒷부분에서 논의), 구문적 유사성에도 불구하고 F571은 언어에 부울 또는 세 가지 값의 리터럴을 도입하지 않는다. F571 기능은 실제로 SQL92에 존재했으며,[13] 1999년에 부울 데이터 유형이 표준에 도입되기 훨씬 전이다. F571 기능은 몇몇 시스템에서 구현되었으며, PostgreSQL이 이를 구현하는 시스템 중 하나이다.

IS UNKNOWN을 SQL의 세 가지 값 논리의 다른 연산자에 추가하면 SQL 세 가지 값 논리가 기능적으로 완전하게 된다.[14] 즉, 논리 연산자가 (조합하여) 상상할 수 있는 모든 세 가지 값 논리 함수를 표현할 수 있다.

F571 기능을 지원하지 않는 시스템에서는 IS UNKNOWN ''p''를 에뮬레이션하기 위해 표현식 ''p''를 Unknown으로 만들 수 있는 모든 인수를 거쳐 IS NULL 또는 기타 NULL 관련 함수로 해당 인수를 테스트할 수 있지만, 이 방법은 더 번거로울 수 있다.

6. 1. 조인 (Joins)

조인 조건에서 Nullable 열을 사용할 때는 주의해야 한다. 특히 Null을 포함하는 테이블은 자체 자연 조인과 ''같지 않으므로'', 관계형 대수에서 임의의 관계 ''R''에 대해 R \bowtie R = R이 참인 반면, SQL 자체 조인은 Null이 있는 모든 행을 제외한다.[15]

SQL `COALESCE` 함수나 `CASE` 식을 사용하여 조인 조건에서 Null 동등성을 "시뮬레이션"할 수 있으며, `IS NULL` 및 `IS NOT NULL` 술어를 조인 조건에서도 사용할 수 있다. 다음은 A와 B 값의 동등성을 테스트하고 Null을 동일한 것으로 처리하는 술어이다.



(A = B) OR (A IS NULL AND B IS NULL)



자연 조인의 경우, 어떤 쿼리가 확실한 정보를 보고하지 못할 수 있음을 보여주는 예시는 다음과 같다.

''J''
F1F2F3
1113
2123
313233



다음 쿼리를 실행하면,



SELECT F1, F3 FROM

(SELECT F1, F2 FROM J) AS F12

NATURAL JOIN

(SELECT F2, F3 FROM J) AS F23;



J에 대한 쿼리 결과는 다음과 같다.

F1F3
3133



하지만 J의 모든 모델에 대한 쿼리 결과는 다음과 같다.

F1F3
1113
2123
3133



이는 하위 쿼리의 프로젝션을 나타내는 Codd 테이블이 열 F12.F2 및 F23.F2의 Null이 실제로 테이블 J 원본의 복사본이라는 사실을 놓치기 때문이다.

SQL 외부 조인은 왼쪽 외부 조인, 오른쪽 외부 조인, 완전 외부 조인을 포함하여 관련 테이블에 누락된 값의 자리 표시자로 자동으로 Null을 생성한다. 예를 들어 왼쪽 외부 조인의 경우, `LEFT OUTER JOIN` 연산자의 오른쪽에 나타나는 테이블에서 누락된 행 대신 Null이 생성된다. 다음은 두 개의 테이블을 사용하여 왼쪽 외부 조인에서 Null 자리 표시자 생성을 보여주는 예시이다.

{|

| valign="top" |

Employee (직원)
IDLastName (성)FirstName (이름)
1Johnson (존슨)Joe (조)
2Lewis (루이스)Larry (래리)
3Thompson (톰슨)Thomas (토마스)
4Patterson (패터슨)Patricia (패트리샤)



| valign="top" |

PhoneNumber (전화번호)
IDNumber (번호)
1555-2323
3555-9876



|}

다음은 이 두 테이블에 대해 왼쪽 외부 조인을 수행하는 SQL 쿼리이다.



SELECT e.ID, e.LastName, e.FirstName, pn.Number

FROM Employee e

LEFT OUTER JOIN PhoneNumber pn

ON e.ID = pn.ID;



이 쿼리의 결과 집합은 SQL이 오른쪽에 있는 ('''PhoneNumber''', 전화번호) 테이블에서 누락된 값에 대한 자리 표시자로 Null을 사용하는 방식을 보여준다.

Query result (쿼리 결과)
IDLastName (성)FirstName (이름)Number (번호)
1Johnson (존슨)Joe (조)555-2323
2Lewis (루이스)Larry (래리)
3Thompson (톰슨)Thomas (토마스)555-9876
4Patterson (패터슨)Patricia (패트리샤)


6. 2. CASE 표현식

SQL은 CASE 표현식의 두 가지 유형의 조건식을 제공한다. 하나는 "단순 CASE"라고 하며 switch 문과 유사하게 작동한다. 다른 하나는 표준에서 "검색된 CASE"라고 하며 if...elseif와 유사하게 작동한다.

단순 `CASE` 표현식은 Null에 대한 DML `WHERE` 절 규칙과 동일한 규칙에 따라 작동하는 암시적 등식 비교를 사용한다. 따라서 ''단순 `CASE` 표현식''은 Null의 존재 여부를 직접 확인할 수 없다. 단순 `CASE` 표현식에서 Null을 확인하면 항상 Unknown이 반환된다.[9]



SELECT CASE i WHEN NULL THEN 'Is Null' -- This will never be returned

WHEN 0 THEN 'Is Zero' -- This will be returned when i = 0

WHEN 1 THEN 'Is One' -- This will be returned when i = 1

END

FROM t;



표현식 `i = NULL`은 열 ''i''에 어떤 값이 포함되어 있든(Null을 포함하는 경우에도) Unknown으로 평가되므로 문자열 `'Is Null'`은 절대 반환되지 않는다.[9]

반면에 "검색된" `CASE` 표현식은 `IS NULL` 및 `IS NOT NULL`과 같은 술어를 조건으로 사용할 수 있다. 다음 예제는 검색된 `CASE` 표현식을 사용하여 Null을 올바르게 확인하는 방법을 보여준다.[11]



SELECT CASE WHEN i IS NULL THEN 'Null Result' -- This will be returned when i is NULL

WHEN i = 0 THEN 'Zero' -- This will be returned when i = 0

WHEN i = 1 THEN 'One' -- This will be returned when i = 1

END

FROM t;



검색된 `CASE` 표현식에서 ''i''가 Null인 모든 행에 대해 문자열 `'Null Result'`가 반환된다.[11]

Oracle의 SQL 방언은 단순 CASE 표현식 대신 사용할 수 있고 두 개의 Null을 동일하게 간주하는 내장 함수 `DECODE`를 제공한다.



SELECT DECODE(i, NULL, 'Null Result', 0, 'Zero', 1, 'One') FROM t;



마지막으로, 이러한 모든 구문은 일치하는 항목이 없으면 NULL을 반환한다. 기본 `ELSE NULL` 절을 갖는다.

6. 3. 절차적 확장 (Procedural extensions)

NULL은 데이터 도메인의 구성원이 아니므로 "값"으로 간주되지 않고 정의되지 않은 값을 나타내는 마커(또는 자리 표시자)로 간주된다.[8] 따라서 NULL과의 비교는 참 또는 거짓이 될 수 없고, 항상 알 수 없음(Unknown)이라는 세 번째 논리적 결과가 된다.[8]

SQL의 3치 논리는 데이터 조작 언어(DML)에서 DML 문과 쿼리의 비교 술어에 나타난다. `WHERE` 절은 술어가 참으로 평가되는 행에 대해서만 DML 문이 작동하도록 한다. 술어가 거짓 또는 알 수 없음으로 평가되는 행은 `INSERT`, `UPDATE` 또는 `DELETE` DML 문에 의해 작동하지 않으며 `SELECT` 쿼리에서 제외된다. 알 수 없음과 거짓을 동일하게 해석하는 것은 Null을 처리할 때 흔히 발생하는 오류이다.[9]

SQL 표준은 Null과 비교할 때 항상 Unknown을 반환하는 기본 비교 연산자 외에도, 두 가지 특수한 Null 관련 비교 술어를 제공한다. `IS NULL` 및 `IS NOT NULL` 술어는 (후위 표기법 구문 사용) 데이터가 Null인지 아닌지를 검사한다.[11]

SQL 표준에는 선택적 기능인 F571 "진리값 테스트"가 포함되어 있다. 이 기능은 세 개의 논리 단항 연산자(부정을 포함하면 6개)를 추가하며, 후위 표기법을 사용한다.[12]

F571 기능은 SQL의 부울 데이터 유형과는 별개이며, 1999년 부울 데이터 유형이 표준에 도입되기 전인 SQL92에 이미 존재했다.[13] PostgreSQL은 F571 기능을 구현하는 시스템 중 하나이다.

SQL 3치 논리에 IS UNKNOWN을 추가하면 기능적으로 완전하게 된다.[14]

6. 4. 외부 조인 (Outer joins)

결과 집합에 Null 자리 표시자가 있는 예시 SQL 외부 조인 쿼리. Null 마커는 결과의 데이터 대신 `NULL` 단어로 표시된다. 결과는 Microsoft SQL Server에서 가져온 것이며, SQL Server Management Studio에 표시된다.


SQL 외부 조인은 관련 테이블에 누락된 값의 자리 표시자로 자동으로 Null을 생성한다. 왼쪽 외부 조인, 오른쪽 외부 조인, 완전 외부 조인이 이에 해당한다. 예를 들어 왼쪽 외부 조인의 경우, `LEFT OUTER JOIN` 연산자의 오른쪽에 나타나는 테이블에서 누락된 행 대신 Null이 생성된다.[4] 다음은 두 개의 테이블을 사용하여 왼쪽 외부 조인에서 Null 자리 표시자 생성을 보여주는 예시다.

첫 번째 테이블 ('''Employee''', 직원)에는 직원 ID 번호와 이름이 포함되어 있으며, 두 번째 테이블 ('''PhoneNumber''', 전화번호)에는 관련 직원 ID 번호와 전화 번호가 포함되어 있다.

Employee (직원)
IDLastName (성)FirstName (이름)
1Johnson (존슨)Joe (조)
2Lewis (루이스)Larry (래리)
3Thompson (톰슨)Thomas (토마스)
4Patterson (패터슨)Patricia (패트리샤)



PhoneNumber (전화번호)
IDNumber (번호)
1555-2323
3555-9876



다음은 이 두 테이블에 대해 왼쪽 외부 조인을 수행하는 SQL 쿼리다.



SELECT e.ID, e.LastName, e.FirstName, pn.Number

FROM Employee e

LEFT OUTER JOIN PhoneNumber pn

ON e.ID = pn.ID;



이 쿼리에서 생성된 결과 집합은 SQL이 오른쪽에 있는 ('''PhoneNumber''', 전화번호) 테이블에서 누락된 값에 대한 자리 표시자로 Null을 사용하는 방식을 보여준다.

Query result (쿼리 결과)
IDLastName (성)FirstName (이름)Number (번호)
1Johnson (존슨)Joe (조)555-2323
2Lewis (루이스)Larry (래리)
3Thompson (톰슨)Thomas (토마스)555-9876
4Patterson (패터슨)Patricia (패트리샤)


6. 5. 집계 함수 (Aggregate functions)

SQL영어의 집계 함수는 `COUNT(*)`를 제외하고는 모두 NULL을 제거하는 단계를 거친다. 따라서 NULL은 계산 결과에 포함되지 않는다.[19]

NULL 제거가 NULL을 0으로 대체하는 것과는 다르다는 점에 유의해야 한다. 예를 들어, 아래 표에서 `AVG(i)` (i 값의 평균)는 `AVG(j)`와 다른 결과를 반환한다.

ij
150150
200200
250250
0



`AVG(i)`는 200 (150, 200, 250의 평균)이고, `AVG(j)`는 150 (150, 200, 250, 0의 평균)이다. SQL에서 `AVG(z)`는 `SUM(z)/COUNT(z)`와 같지만, `SUM(z)/COUNT(*)`와는 다르다.[3]

6. 6. 그룹화, 정렬 및 일부 집합 연산

SQL은 `GROUP BY`, `ORDER BY`, `UNION`, `INTERSECT`, `EXCEPT` 등에서 `NULL`을 처리하기 위해 "구별되지 않음" 정의를 사용한다.[20]

`NULL`은 어떠한 데이터 도메인의 구성원도 아니기 때문에, "값"으로 간주되지 않고 정의되지 않은 값을 나타내는 마커(또는 자리 표시자)로 간주된다.

`NULL` 처리에 있어서 "구별되지 않음" 정의를 사용하는 다른 SQL 연산, 절 및 키워드에는 다음이 포함된다.

  • `ROW_NUMBER`와 같은 순위 및 윈도우 함수의 `PARTITION BY` 절
  • 행 비교/제거 목적으로 `NULL`을 동일하게 처리하는 `UNION`, `INTERSECT` 및 `EXCEPT` 연산자
  • `SELECT` 쿼리에 사용되는 `DISTINCT` 키워드


`NULL`이 서로 같지 않다는 원칙(오히려 결과는 알 수 없음)은 `UNION` 연산자에 대한 SQL 사양에서 실제로 위반되는데, 이는 `NULL`을 서로 식별하기 때문이다.[4] 결과적으로, SQL의 일부 집합 연산(예: 합집합 및 차집합)은 `NULL`과의 명시적 비교와 관련된 연산과는 달리 확실한 정보를 나타내지 않는 결과를 생성할 수 있다.

SQL 표준은 `NULL`에 대한 기본 정렬 순서를 명시적으로 정의하지 않는다. 대신, 준수 시스템에서 `ORDER BY` 목록의 `NULLS FIRST` 또는 `NULLS LAST` 절을 각각 사용하여 `NULL`을 모든 데이터 값보다 먼저 또는 나중에 정렬할 수 있다. 그러나 모든 DBMS 공급업체가 이 기능을 구현하는 것은 아니다.[18]

6. 7. 인덱스 연산

일부 SQL 제품은 NULL을 포함하는 키에 대한 인덱싱을 수행하지 않는다. 예를 들어, PostgreSQL 8.3 이전 버전에서는 B-tree 인덱스가 NULL 값을 인덱싱하지 않았다.[21] 인덱스가 고유성을 강제하는 경우에도 NULL은 인덱스에서 제외되었고, NULL 간의 고유성은 강제되지 않았다.[22]

SQL:2003에 정의된 동작에 따라 NULL을 ''구별되지 않는'' 것으로 처리하여 인덱싱하는 방법도 있다. 예를 들어, Microsoft SQL Server에서는 인덱싱 시 NULL을 동일한 것으로 간주한다.[23]

이러한 두 가지 인덱싱 전략은 모두 SQL:2003에 정의된 Null의 동작과 일치한다. 그러나 인덱싱 방법론은 SQL:2003 표준에서 명시적으로 정의되지 않았기 때문에, NULL에 대한 인덱싱 전략은 각 데이터베이스 벤더가 자체적으로 설계하고 구현한다.

7. NULL 처리 함수

SQL은 `NULLIF`와 `COALESCE`라는 두 가지 함수를 통해 Null을 명시적으로 처리한다. 이 두 함수는 `CASE` 표현식의 축약형이다.[24]

7. 1. NULLIF

sql

NULLIF(value1, value2)

```

`NULLIF` 함수는 두 개의 매개변수를 받는다. 첫 번째 매개변수가 두 번째 매개변수와 같으면 `NULLIF`는 Null을 반환한다. 그렇지 않으면 첫 번째 매개변수의 값을 반환한다.[24]

따라서 `NULLIF`는 다음 `CASE` 표현식의 약어이다.[24]

```sql

CASE WHEN value1 = value2 THEN NULL ELSE value1 END

7. 2. COALESCE

`COALESCE` 함수는 파라미터 목록을 받아 목록에서 처음으로 Null이 아닌 값을 반환한다.[24]

```sql

COALESCE(value1, value2, value3, ...)

```

`COALESCE`는 다음 SQL `CASE` 표현식의 약어이다.[24]

```sql

CASE

WHEN value1 IS NOT NULL THEN value1

WHEN value2 IS NOT NULL THEN value2

WHEN value3 IS NOT NULL THEN value3

...

END

```

일부 SQL DBMS는 `COALESCE`와 유사한 벤더별 함수를 구현한다. 예를 들어, Transact-SQL에서는 `ISNULL` 함수 또는 `COALESCE`와 기능적으로 유사한 다른 함수를 구현한다. (Transact-SQL의 `IS` 함수에 대한 자세한 내용은 `Is` 함수를 참조).

7. 3. NVL (Oracle)

오라클의 `NVL` 함수는 두 개의 매개변수를 받는다. 이 함수는 첫 번째 NULL이 아닌 매개변수를 반환하거나, 모든 매개변수가 NULL인 경우 NULL을 반환한다.

`COALESCE` 표현식은 다음과 같이 동등한 `NVL` 표현식으로 변환될 수 있다.

```mysql

COALESCE ( val1, ... , val{n} )

```

는 다음과 같이 바뀐다.

```mysql

NVL( val1 , NVL( val2 , NVL( val3 , … , NVL ( val{n-1} , val{n} ) … )))

```

이 함수의 사용 사례는 `NVL(SALARY, 0)`처럼 표현식에서 NULL을 값으로 바꾸는 것이다. 즉, '`SALARY`가 NULL이면 0으로 바꿉니다'라는 의미이다.

하지만 한 가지 주목할 만한 예외가 있다. 대부분의 구현에서 `COALESCE`는 첫 번째 NULL이 아닌 값에 도달할 때까지 매개변수를 평가하는 반면, `NVL`은 모든 매개변수를 평가한다. 이것은 몇 가지 이유로 중요한데, 첫 번째 NULL이 아닌 매개변수 ''이후''의 매개변수는 함수일 수 있으며, 이는 계산 비용이 많이 들거나, 유효하지 않거나, 예상치 못한 부작용을 일으킬 수 있기 때문이다.

8. NULL 및 미지의 데이터 타입

`NULL` 리터럴은 SQL에서 타입이 지정되지 않으며, 정수, 문자 또는 다른 특정 데이터 타입으로 지정되지 않는다.[25] 이 때문에 널을 특정 데이터 타입으로 명시적으로 변환해야 하는 경우가 종종 있다. 예를 들어, 함수 오버로딩이 RDBMS에서 지원되는 경우, SQL은 널이 전달된 매개변수를 포함하여 모든 매개변수의 데이터 타입을 알지 못하면 올바른 함수로 자동적으로 해결하지 못할 수 있다.

`NULL` 리터럴에서 특정 타입의 널로 변환하려면 SQL-92에 도입된 `CAST`를 사용한다. 예를 들어:



CAST (NULL AS INTEGER)



위 코드는 INTEGER 타입의 부재 값을 나타낸다.

Unknown의 실제 타이핑(NULL 자체와 구별되는지 여부)은 SQL 구현에 따라 다르다. 예를 들어, 다음 코드는



SELECT 'ok' WHERE (NULL <> 1) IS NULL;



일부 환경(SQLite 또는 PostgreSQL)에서는 NULL 부울 값을 Unknown과 통합하여 구문 분석하고 성공적으로 실행되지만, 다른 환경(SQL Server Compact)에서는 구문 분석에 실패한다. MySQL은 이와 관련하여 PostgreSQL과 유사하게 동작한다(단, MySQL은 TRUE와 FALSE를 일반 정수 1과 0과 다르지 않게 취급한다는 사소한 예외가 있다). PostgreSQL은 또한 `IS UNKNOWN` 술어를 구현하여 삼중 값 논리적 결과가 Unknown인지 테스트할 수 있지만, 이것은 단지 구문 설탕일 뿐이다.

9. BOOLEAN 데이터 타입

SQL:1999 표준은 BOOLEAN 데이터 타입을 SQL에 도입했지만, 이는 선택적인 기능이다(코드 T031).[26]

SQL BOOLEAN은 `NOT NULL` 제약 조건이 없을 경우, TRUE, FALSE, 그리고 UNKNOWN의 세 가지 진리값을 가질 수 있다. 표준에 따르면 NULL과 UNKNOWN은 같은 의미로 사용될 수 있다.[27][28]

부울 형식은 UNKNOWN 리터럴의 동작 방식 때문에 비판을 받기도 한다. UNKNOWN은 NULL과 동일시되기 때문에 자기 자신과 비교해도 같을 수 없다.[29]

PostgreSQL 같은 일부 SQL 구현에서는 Null이 UNKNOWN BOOLEAN을 포함한 모든 UNKNOWN 결과를 나타내는 데 사용된다. PostgreSQL은 UNKNOWN 리터럴을 구현하지 않지만, IS UNKNOWN 연산자를 통해 삼중 값 논리 결과가 Unknown인지 확인할 수 있다. 2012년 기준으로, 다른 주요 데이터베이스 공급업체 대부분은 부울 형식을 지원하지 않는다.[30] Oracle의 PL/SQL은 BOOLEAN 변수를 지원하며, 이 변수에 NULL을 할당할 수 있고, 그 값은 UNKNOWN과 동일하게 간주된다.[31]

10. 논란

E. F. 콧(E. F. Codd)은 1975년 ACM-SIGMOD ''FDT Bulletin'' 논문과 1979년 ''ACM 데이터베이스 시스템 트랜잭션'' 논문에서 관계형 모델의 누락된 데이터를 표현하는 방법으로 널(Null)을 제안했다.[38] 1979년 논문에서는 삼진 논리를 이용한 널 값 비교와 산술 연산에서의 널 전파 등을 상세히 설명했다.[4] 코드는 1985년 ''컴퓨터 월드'' 기고를 통해 모든 RDBMS가 널을 지원해야 한다고 강조했다.[39][40]

1986년 SQL 표준은 IBM System R 구현을 거쳐 콧의 제안을 채택했다. 돈 챔벌린(Don Chamberlin)은 널이 SQL의 가장 논란이 많은 기능 중 하나임을 인정하면서도, 누락된 정보 처리 비용 절감 및 프로그래머 부담 감소 등 실용적인 측면을 들어 널 설계를 옹호했다.[3]

코드는 1990년 저서에서 SQL 표준의 단일 널이 부적절하며, '누락되었지만 적용 가능'과 '누락되었지만 적용 불가능'을 나타내는 두 개의 널 마커로 대체해야 한다고 주장했다.[33] 이는 4진 논리 시스템 도입을 의미했지만, 복잡성 문제로 널리 받아들여지지 않았다.

크리스 데이트와 휴 다윈은 SQL NULL 구현에 결함이 있다며 제거를 주장했다.[34] 이들은 NULL 처리의 불일치와 결함을 지적하며, NULL 개념 자체가 관계형 모델에서 제거되어야 한다고 주장했다.[35]

NULL은 폐쇄 세계 가정을 위반하고 개방 세계 가정을 도입한다는 논쟁도 있다.[36] 폐쇄 세계 가정은 데이터베이스에 명시된 것만 참이고 나머지는 거짓이라고 가정하지만, NULL은 일부 항목을 알 수 없음으로 간주하여 데이터베이스 지식을 불완전하게 만든다.

10. 1. 흔한 실수

NULL은 0(영)이나 빈 문자열(SQL에서 `''`로 표시되는 길이가 0인 문자열 값)과 혼동되는 경우가 많다. 그러나 NULL은 SQL 표준에 의해 빈 문자열 및 숫자 값 `0`과 모두 다르게 정의된다. NULL은 값이 없음을 나타내는 반면, 빈 문자열과 숫자 0은 모두 실제 값을 나타낸다.

흔한 실수 중 하나는 `=` 연산자를 사용하여 NULL을 찾으려고 시도하는 것이다. SQL 표준에 따르면 이는 잘못된 구문이다. 대부분의 구현에서는 이 구문을 허용하지만, 이 표현식은 `UNKNOWN`으로 평가된다. 따라서 NULL이 있는 행은 검색되지 않는다. NULL이 있는 행을 검색하려면 `= NULL` 대신 `IS NULL` 술어를 사용해야 한다.[32]

```sql

SELECT *

FROM sometable

WHERE num = NULL; -- "WHERE num IS NULL"이어야 합니다.

```

`WHERE` 절이나 조건문에서 열의 값을 상수와 비교할 때, 해당 필드에 NULL이 포함된 경우 상수보다 "작거나 같지 않다"고 잘못 가정하는 경우가 많다. 그러나 이러한 표현식은 '알 수 없음'을 반환한다.

```sql

SELECT *

FROM sometable

WHERE num <> 1; -- num이 NULL인 행은 반환되지 않습니다.

  • - 많은 사용자의 기대와는 다릅니다.

```

이는 동일성 법칙이 SQL 논리에서 제한되기 때문에 발생한다. `NULL` 또는 `UNKNOWN` 진리 값을 사용한 동등성 비교는 항상 `UNKNOWN`을 반환한다. 이는 부분 동치 관계이며, SQL을 ''비반사적 논리''의 예로 만든다.[32]

NULL은 빈 문자열과 혼동되기도 한다. 문자열의 문자 수를 반환하는 `LENGTH` 함수에 NULL이 전달되면, NULL을 반환한다. 이는 3치 논리에 익숙하지 않은 사용자에게 예기치 않은 결과를 초래할 수 있다.

```sql

SELECT *

FROM sometable

WHERE LENGTH(string) < 20; -- 문자열이 NULL인 행은 반환되지 않습니다.

```

일부 데이터베이스 인터페이스 프로그램(또는 오라클과 같은 데이터베이스 구현)에서 NULL이 빈 문자열로 보고되고, 빈 문자열이 NULL로 저장될 수 있다는 점은 혼란을 더욱 가중시킨다.

10. 2. 비판

SQL영어의 NULL 구현은 크리스 데이트와 휴 다윈에 의해 결함이 있어 제거되어야 한다는 비판을 받았다.[34] 이들은 NULL 처리, 특히 집계 함수에서의 구현상의 불일치와 결함을 지적하며, NULL 개념 자체가 관계형 모델에서 제거되어야 한다고 주장했다.[35]

10. 3. 폐쇄 세계 가정 (Closed-world assumption)

NULL은 폐쇄 세계 가정 모델을 위반하여 데이터베이스에 개방 세계 가정을 도입한다는 논쟁이 있다.[36] 폐쇄 세계 가정은 "데이터베이스에 명시적 또는 묵시적으로 진술된 모든 것은 참이고, 그 외 모든 것은 거짓이다."[37]라고 명시한다. 이는 데이터베이스에 저장된 세계에 대한 지식이 완전하다고 가정한다. 그러나 NULL은 일부 항목이 알 수 없는 것으로 간주되어, 데이터베이스에 저장된 세계 지식을 불완전하게 만드는 개방 세계 가정하에서 작동한다.

참조

[1] 간행물 Is Your Database Really Relational? 1985-10-14
[2] 간행물 Does Your DBMS Run By The Rules? 1985-10-21
[3] 서적 A Complete Guide to DB2 Universal Database https://books.google[...] Morgan Kaufmann
[4] 서적 Logical approaches to incomplete information: a survey https://books.google[...] Kluwer Academic Publishers
[5] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[6] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[7] 웹사이트 Handle empty strings when migrating from Oracle to PostgreSQL ! AWS Database Blog https://aws.amazon.c[...] 2022-05-23
[8] 서적 ISO/IEC 9075-1:2003, "SQL/Framework" http://www.iso.org ISO/IEC
[9] 간행물 Four Rules for Nulls http://www.sqlserver[...] Red Gate Software 2005-06-27
[10] 서적 Semantics in Databases. Second International Workshop Dagstuhl Castle, Germany, January 7–12, 2001. Revised Papers
[11] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[12] 서적 An introduction to database systems Pearson Education
[13] 서적 Understanding The New SQL: A Complete Guide https://books.google[...] Morgan Kaufmann
[14] 서적 Relational database writings, 1991-1994 Addison-Wesley
[15] 서적 An introduction to database systems Pearson Education
[16] 간행물 Incomplete information in relational databases 1984
[17] 서적 Foundations of Databases https://archive.org/[...] Addison-Wesley
[18] 간행물 Null Versus Null? http://www.sqlserver[...] Red Gate Software 2007-02-26
[19] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[20] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[21] 웹사이트 PostgreSQL 8.0.14 Documentation: Index Types http://www.postgresq[...] PostgreSQL 2008-11-06
[22] 웹사이트 PostgreSQL 8.0.14 Documentation: Unique Indexes http://www.postgresq[...] PostgreSQL 2008-11-06
[23] 웹사이트 Creating Unique Indexes http://msdn2.microso[...] PostfreSQL 2008-11-06
[24] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[25] 서적 SQL:1999: Understanding Relational Language Components https://archive.org/[...] Morgan Kaufmann
[26] 웹사이트 ISO/IEC 9075-1:1999 SQL Standard ISO
[27] 서적 SQL and Relational Theory: How to Write Accurate SQL Code https://books.google[...] O'Reilly Media, Inc.
[28] 문서 ISO/IEC 9075-2:2011 §4.5
[29] 서적 Introduction to Databases With Web Applications https://books.google[...] Pearson Education Canada
[30] 웹사이트 Survey of BOOLEAN data type implementation http://troels.arvin.[...]
[31] 서적 Oracle PL/SQL Programming O'Reilly Media, Inc.
[32] 간행물 Classical Logic or Non-Reflexive Logic? A case of Semantic Underdetermination
[33] 서적 The Relational Model for Database Management Pearson PLC|Addison Wesley Publishing Company
[34] 웹사이트 The Third Manifesto http://www.thethirdm[...] 2007-05-29
[35] 웹사이트 The Askew Wall http://www.dcs.warwi[...] 2007-05-29
[36] 서적 Database in Depth: Relational Theory for Practitioners O'Reilly Media, Inc. 2005-05
[37] 웹사이트 Abstract: The Closed World Assumption http://www.sfdama.or[...] Data Management Association, San Francisco Bay Area Chapter 2007-05-29
[38] 간행물 Logical approaches to incomplete information: a survey http://books.google.[...] Kluwer Academic Publishers
[39] 저널 Is Your Database Really Relational? 1985-10-14
[40] 저널 Does Your DBMS Run By The Rules? 1985-10-21
[41] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[42] 서적 ISO/IEC 9075-2:2003, "SQL/Foundation" ISO/IEC
[43] 서적 ISO/IEC 9075-1:2003, "SQL/Framework" http://www.iso.org ISO/IEC



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com