SQL : 빈 문자열 대 NULL 값 수 있다고

나는이 주제가 논란의 여지가 있으며 인터넷에 떠 다니는 다양한 기사 / 의견이 많다는 것을 알고 있습니다. 불행히도, 대부분의 사람들은 NULL과 빈 문자열의 차이점이 무엇인지 알지 못한다고 가정합니다. 따라서 조인 / 집계로 놀라운 결과에 대해 이야기하고 일반적으로 좀 더 고급 SQL 레슨을 수행합니다. 이렇게함으로써, 그들은 요점을 절대로 그리워하지 않으므로 나에게는 쓸모가 없습니다. 희망적 으로이 질문과 모든 대답은 주제를 조금 앞으로 나아갈 것입니다.

열 중 하나가 varchar 유형의 전자 메일 주소 인 개인 정보 (이름, 출생 등)가있는 테이블이 있다고 가정합니다. 어떤 이유로 어떤 사람들은 이메일 주소를 제공하고 싶지 않을 수 있다고 가정합니다. 이러한 데이터 (이메일없이)를 테이블에 삽입 할 때 사용 가능한 두 가지 선택 사항이 있습니다. 셀을 NULL로 설정하거나 빈 문자열 ( ”)로 설정하십시오. 하나의 솔루션을 다른 솔루션으로 선택하는 모든 기술적 의미를 알고 있다고 가정하고 두 시나리오에 대해 올바른 SQL 쿼리를 만들 수 있습니다. 문제는 두 값이 기술 수준에서 다르더라도 논리적 수준에서 정확히 동일합니다. NULL을보고 ”나는 한 가지 결론에 도달했습니다 : 나는 그 사람의 이메일 주소를 모른다. 아무리 노력해도 아무리 노력해도 NULL 또는 빈 문자열을 사용하여 전자 메일을 보낼 수 없었으므로 대부분의 SMTP 서버는 내 논리와 일치합니다. 따라서 값을 모르고 빈 문자열을 나쁜 것으로 간주하는 경우 NULL을 사용하는 경향이 있습니다.

동료들과의 격렬한 토론 후에 두 가지 질문이 나왔습니다.

  1. 알 수없는 값으로 빈 문자열을 사용하면 데이터베이스가 사실에 대해 “거짓”하게된다고 가정하는 것이 맞습니까? 더 정확하게 말하면, 가치가 무엇인지 아닌지에 대한 SQL의 아이디어를 사용하여 결론을 내릴 수 있습니다. 전자 메일 주소는 null이 아니라는 것을 알면됩니다. 그러나 나중에 전자 메일을 보내려고 할 때 모순되는 결론에 도달 할 것입니다. 아니요, 전자 메일 주소가 없습니다. @! # $ 데이터베이스가 거짓말을해야합니다!

  2. 빈 문자열 ”이 중요한 정보 (값과 값이 아닌)를 전달하는 좋은 방법이 될 수있는 논리적 시나리오가 있습니까? 때로는 실제 값과 NULL과 함께 빈 문자열을 사용하는 것이 좋다고 주장하는 많은 게시물을 보았지만 지금까지는 SQL / DB 디자인 측면에서 논리적 인 시나리오는 보지 못했습니다.

추신 : 어떤 사람들은 그것이 개인적인 취향의 문제라는 대답에 유혹을받을 것입니다. 동의하지 않습니다. 나에게 중요한 결과를 가진 디자인 결정입니다. 그래서 이것에 대한 의견이 논리 및 / 또는 기술적 인 이유에 의해 뒷받침되는 답변을보고 싶습니다.



답변

NULL“이메일 주소 없음”에 대한 올바른 선택 이라고 말하고 싶습니다 . 있습니다 많은 “무효”이메일 주소, 그리고 “”(빈 문자열) 하나에 불과합니다. 예를 들어 “foo”는 유효한 이메일 주소가 아니며 “a @ b @ c”는 유효하지 않습니다. 따라서 “”가 유효한 이메일 주소가 아니기 때문에 “이메일 주소 없음”값으로 사용할 이유가 없습니다.

“”가 “이 열에 값이 없습니다”라고 말하는 올바른 방법이 아니라고 말하는 것이 옳습니다. “” 값입니다.

“”가 유효한 값일 NULL수있는 예는 개인의 중간 이름 일 수 있습니다. 모든 사람에게 중간 이름이있는 것은 아니므로 “중간 이름 없음”( “”-빈 문자열)과 “중간 이름이 있는지 없는지 모르겠습니다”( NULL)를 구분해야합니다. 빈 문자열이 여전히 열에 유효한 값인 다른 많은 예가있을 수 있습니다.


답변

위의 의견에 동의하면서이 주장을 주요 동기로 추가하겠습니다.

  1. NULL로 표시된 필드가 선택 필드 인 데이터베이스를 보는 모든 프로그래머에게는 분명합니다. (즉, 레코드에는 해당 열에 대한 데이터가 필요하지 않습니다)
  2. NOT NULL 필드를 표시하면 프로그래머는 직관적으로 해당 필드가 필수 필드라고 가정해야합니다.
  3. 널 (null)을 허용하는 필드에서 프로그래머는 빈 문자열이 아닌 널 (null)을 보게됩니다.

자체 문서화 직관적 인 코딩을 위해 빈 문자열 대신 NULL을 사용하십시오.


답변

귀하의 예에서 웹 필드에서 직접 값을 얻는 경우 빈 문자열을 사용합니다. 사용자가 이메일을 제공하지 않도록 지정할 수 있거나 삭제할 수있는 경우 NULL입니다.

다음은 고려할 수있는 사항과의 링크입니다. https://stackoverflow.com/questions/405909/null-vs-empty-when-dealing-with-user-input/405945#405945

— 편집 (토마스 의견에 대한 답변) —

데이터베이스는 데이터베이스를 사용하는 응용 프로그램 없이는 작동하지 않습니다. 응용 프로그램에서 제대로 사용할 수없는 경우 NULL 또는 ”을 정의하면 값이 없습니다.

사용자가 LONG 양식을 채우고 Enter 키를 누르면 서버에 지속 요청을 보내는 예를 고려하십시오. 그는 이메일을 입력하는 중일 수 있습니다. 아마도 당신은 그가 가진 모든 것을 이메일 필드에 저장하고 싶을 것입니다. 그가 한 문자 만 입력하면 어떻게 되나요? 한 문자를 입력 한 다음 삭제하면 어떻게됩니까? 이메일이 필요하지 않은 경우 때때로 사용자가 이메일을 삭제하려고합니다. 필드를 지우는 가장 쉬운 방법입니다. 또한 이메일이 필요하지 않은 경우 보내기 전에 이메일을 확인하는 것이 좋습니다.

또 다른 예 : 사용자는 전자 메일을 spamto @ [bigcompany] .com으로 제공합니다.이 경우 전자 메일을 보낼 필요가 없으므로 전자 메일이 존재하고 유효한 경우에도있을 수 있습니다. 그 중 하나를 저렴하게 보낼 수는 있지만 매일 구독 할 수있는 전자 메일을 가진 10K 사용자가 있으면 그러한 유효성 검사로 많은 시간을 절약 할 수 있습니다.


답변

나는 Dean Hardings의 답변이 이것을 정말로 훌륭하게 다루고 있다고 생각합니다. DB 수준에서 NULL과 빈 문자열에 대해 이야기 할 때 다른 데이터 유형에 대해 생각해야한다고 언급하고 싶습니다. 날짜가 제공되지 않을 때 최소 날짜를 저장 하시겠습니까? 또는 int가 제공되지 않은 경우 -1? 값이 없을 때 값을 저장하면 값이 아닌 전체 범위를 추적해야합니다. 각 데이터 유형에 대해 적어도 하나 이상 (-1이 실제 값인 경우 더 많을 수 있으므로 대안이 더 필요함) 응용 프로그램 수준에서 “퍼지 (fudgy)”를 수행해야하는 경우 한 가지이지만 데이터를 오염시킬 필요는 없습니다.


답변

불행히도 오라클은 길이가 0 인 VARCHAR 문자열 표현과 NULL 표현을 혼동했습니다. 둘 다 내부적으로 값이 0 인 단일 바이트로 표시됩니다. 이것은 토론을 훨씬 더 어렵게 만듭니다.

NULL을 둘러싼 많은 혼란이 3 값 논리를 중심으로 합니다. 다음 의사 코드를 고려하십시오.

if ZIPCODE = NULL
    print "ZIPCODE is NULL"
else if ZIPCODE <> NULL
    print "ZIPCODE is not NULL"
else print "Something unknown has happened"

세 번째 메시지를 기대하지는 않지만 세 가지 가치있는 논리에서 얻을 수 있습니다. 세 가지 가치있는 논리는 사람들을 수많은 버그로 이끌고 있습니다.

혼란의 또 다른 원인은 밤에 짖지 않은 개의 추론을 그리는 것과 같이 데이터가 없기 때문에 추론을 이끌어내는 것입니다. 종종 이러한 추론은 NULL의 작가가 cnvey하려는 의도가 아니 었습니다.

그럼에도 불구하고 NULL은 데이터의 부재를 잘 처리하고 원하는 결과를 정확하게 생성하는 상황이 많이 있습니다. 한 가지 예는 선택적 관계의 외래 키입니다. 주어진 행에 관계가 없음을 나타 내기 위해 NULL을 사용하는 경우 해당 행은 예상 한대로 내부 조인에서 제거됩니다.

또한 저장된 데이터에서 NULLS를 완전히 피하더라도 (6 번째 일반 형식) 외부 조인을 수행하더라도 NULLS를 처리해야합니다.


답변

널을 사용하십시오.

단순히 테이블의 필드를 널 입력 가능하게 만들 때 ”값을 저장할 필요는 없습니다. 쿼리도 더욱 명확 해집니다.

전자 메일 주소를 가진 사용자를 찾으려면 어떤 SQL 쿼리가 더 명확하고 읽기 쉬운가?

  1. SELECT * FROM Users WHERE email_address != ''

  2. SELECT * FROM Users WHERE email_address IS NOT NULL

  3. SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL

나는 2라고 말할 것입니다. 나쁜 데이터가 저장된 경우 3이 더 강력하지만.

선택 사항 인 양식의 이메일 주소의 경우 테이블에도 반영되어야합니다. SQL에서 널 입력 가능 필드는 알 수 없음을 의미합니다.

나는 단순히 나쁜 디자인 이외의 테이블에 빈 문자열을 저장하는 데 합리적인 비즈니스 가치를 생각할 수 없습니다. 문자열 값 ‘NULL’또는 ‘BLANK’를 저장하는 것과 비슷하며 개발자 가 null 또는 빈 문자열 이라고 가정 하도록합니다. 나에게 그것은 나쁜 디자인입니다. NULL이있을 때 왜 저장합니까 ??

NULL을 사용하면 모든 사람들이 조금 더 행복해질 것입니다.

더 많은 정보:

SQL은 True, False 및 Unknown의 3 가지 논리 시스템을 사용합니다.

더 자세하고 자세한 설명을 보려면 개발자가 SQL 쿼리 – TRUE 및 FALSE를 넘어서 읽는 것이 좋습니다 .


답변

특정 기술 질문의 경우 문제는 null 대 빈 문자열이 아니며 유효성 검사 실패 입니다. 빈 문자열은 유효한 이메일 주소가 아닙니다!

철학적 질문에 대한 대답은 비슷합니다. 입력을 확인하십시오. 빈 문자열이 해당 필드에 유효한 값이면이를 예상하고 코드화하십시오. 그렇지 않은 경우 null을 사용하십시오.

빈 문자열은 질문에 대답하기위한 유효한 입력이 될 것입니다. 마임은 기린에게 무엇을 말했습니까?