BBC 에서 기사 를 읽었습니다 . 그들이 말한 예 중 하나는 성이 'Null'인 사람들이 일부 웹 사이트에 세부 정보를 입력하는 데 문제가 있다는 것입니다.
그들이 직면 한 오류에 대한 설명은 없습니다.
그러나 내가 아는 한 문자열 'Null'이며 실제 Null 값은 완전히 다릅니다 (데이터베이스 관점에서).
이것이 왜 데이터베이스에서 문제를 일으키는가?
BBC 에서 기사 를 읽었습니다 . 그들이 말한 예 중 하나는 성이 'Null'인 사람들이 일부 웹 사이트에 세부 정보를 입력하는 데 문제가 있다는 것입니다.
그들이 직면 한 오류에 대한 설명은 없습니다.
그러나 내가 아는 한 문자열 'Null'이며 실제 Null 값은 완전히 다릅니다 (데이터베이스 관점에서).
이것이 왜 데이터베이스에서 문제를 일으키는가?
답변:
데이터베이스 문제를 일으키지 않습니다. 데이터베이스를 이해하지 못하는 개발자가 작성한 응용 프로그램에서 문제가 발생합니다. 문제의 근원은 많은 데이터베이스 관련 소프트웨어가 NULL 레코드를 문자열로 표시한다는 것 NULL
입니다. 응용 프로그램이 NULL 레코드의 문자열 형식을 사용하는 경우 (대 / 소문자를 구분하지 않는 비교 작업 사용) 이러한 응용 프로그램은 모든 "null"
문자열을 NULL로 간주 합니다. 결과적으로 Null이라는 이름은 해당 응용 프로그램에서 존재하지 않는 것으로 간주됩니다.
해결책은 NOT NULL
데이터베이스에서와 같이 널이 아닌 열을 선언 하고 문자열 조작을 데이터베이스 레코드에 적용하지 않는 것입니다. 대부분의 언어에는 문자열 수준의 인터페이스가 필요없는 우수한 데이터베이스 API가 있습니다. SQL 인젝션과 같은 다른 실수를 줄이기 때문에 항상 선호해야합니다.
NOT NULL
다른 사람들에게 전체 문제가 발생할 수 있습니다. "일부 개인은 이름과 성이 아닌 단일 이름 만 갖습니다."
특정 질문에 대답하기 위해 웹 양식과 데이터베이스 사이의 이벤트 체인을 따라 여러 단계가 있습니다. 성 Null
이 NULL
값 으로 잘못 해석 되면 시스템은 완벽하게 유효한 이름을 유효하지 않은 것으로 거부 할 수 있습니다. 이것은 amon에서 설명한 대로 데이터베이스 계층에서 발생할 수 있습니다 . 우연히 이것이 이것이 특정 문제라면 데이터베이스는 아마도 Bobby Tables 공격 이라는 SQL 인젝션에 열려있을 것입니다 . 체인에서 문제를 일으킬 수있는 또 다른 단계 는 직렬화 프로세스 입니다.
전체 기사는 더 큰 문제에 관한 것이 었습니다. 세상은 우리의 가정에 항상 부합하지 않는 큰 지저분한 곳입니다. 이것은 응용 프로그램을 국제화하려고 할 때 특히 분명합니다. 하루 가 끝나면 애플리케이션이 데이터를 올바르게 처리하고 인코딩하도록해야합니다 . 점점 더 복잡한 엣지 케이스를 지원하기 위해 얼마나 많은 리소스를 사용할 것인지 결정하는 것은 비즈니스에 달려 있습니다. 포괄적 인 지원을 완벽하게 지원하지만 "공식적으로 Prince로 알려진 아티스트"가 데이터베이스에서 자신의 이름을 나타 내기 위해 유니 코드 문자를 사용해야한다고 결정하는 경우 이해합니다.
INSERT INTO users (first, last) VALUES($first, $last)
평가 INSERT INTO users (first, last) VALUES(Jennifer, Null)
) 이름 이 유효 하지 않은 모든 SQL 키워드 또는 열 이름은 오류를 발생 시키며 레코드도 삽입하지 않습니다. 원인은 더 복잡해야합니다.
프로그래밍 문제 일 가능성이 높습니다. NULL이 전달되는 방법에 대한이 답변을 보면 "Mr. Null"인 경우 원치 않는 동작이 발생할 수 있습니다.
https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string
일부 데이터 요소가 NULL로 전달 된 경우 데이터는 데이터베이스에서 데이터베이스 널로 보간됩니다.
"NULL"! = 데이터베이스 널
일부 사용 사례 및 관련 동작 ...
데이터베이스에서 성이 null이 아닌 것으로 표시되었다고 가정 해 봅시다. 이제 데이터가 삽입되면 NULL로 해석되어 삽입에 실패합니다.
또 다른 경우는 데이터베이스에서 성이 널 입력 가능하다고 가정합니다. Mr. NULL이 삽입되고 "NULL"과 동일하지 않은 DBNull.Value로 변환됩니다. 삽입 후에는 Mr. Null을 찾을 수 없습니다. 그의 성은 "NULL"이 아니라 실제로 데이터베이스 널값이기 때문입니다.
따라서 두 가지 문제가 있습니다. @Amon이 지적했듯이 데이터베이스 자체에는 null과 관련된 문제가 없지만 공급 업체마다 차이가 있으므로 각 RDMS 인스턴스에서 null이 처리되는 방식을 이해해야합니다.
나는 문제가 조잡한 프로그래밍과 일부 SQL 구현의 잘못된 디자인 때문이라고 생각합니다. "널"이름은 항상 따옴표로 표시하고 해석해야합니다. 데이터베이스 값인 null은 항상 따옴표없이 표시해야합니다. 그러나 임시 코드를 작성할 때는 "무엇이든 할 것"패러다임에 빠지기 쉽고 인용 부호없는 형태의 문자열로 여겨지는 것을 받아들입니다.
이것은 다른 유형의 데이터라는 사실에 의해 더욱 복잡해집니다. 예를 들어 숫자는 해석이 모호하지 않기 때문에 어느 형식으로나 받아 들여질 수 있습니다.
근본적으로 문제는 "널 (null)"이라는 용어는 두 개의 서로 다른 데이터베이스 개념이 적용되며 때로는 컨텍스트를 사용하여 서로 구별하는 것입니다.
상황에 따라 이러한 개념을 구별하기에 충분할 수 있지만 실제로 그렇지 않은 경우가 있습니다. 예를 들어, 검색어를 보유하기 위해 레코드를 사용하는 경우 "이름이없는 [다른 사람은 이름없이]"라는 말과 "이름이 [ 무엇이든]하지만 성을 모르는 사람입니다. " 많은 데이터베이스 엔진은 하나의 의미 또는 다른 의미에 대한 편견을 가지고 있지만 모두 동일하지는 않습니다. 데이터베이스 엔진이 한 방향으로 작동 할 것으로 예상하는 코드는 다르게 실행되는 다른 엔진에서 실행될 경우 오작동 할 수 있습니다.
기존 답변의 대부분은 응용 프로그램의 비 SQL 부분에 중점을 두지 만 SQL에도 문제가있을 수 있습니다.
사용자의 성을 사용할 수없는 레코드를 필터링하도록 지시받은 경우 SQL을 잘 모르는 사람이 필터를 작성할 수 있습니다 WHERE u.lastname != 'NULL'
. SQL이 작동하는 방식 때문에 u.lastname IS NOT NULL
모든 NULL
레코드가 필터링 되는지 여부를 확인하는 것으로 나타납니다 . 모든 비 NULL
기록은 남아 있습니다.
의 경우를 제외하고는 u.lastname == 'NULL'
테스트 중에 사용 가능한 레코드가 없었을 수 있습니다.
SQL이 일종의 프레임 워크에 의해 생성되는 경우, 프레임 워크가 NULL
매개 변수 가 없는지 확인하기 위해 쉽게 액세스 할 수있는 방법을 노출하지 않으며 누군가가 "이봐, 내가 문자열을 전달 NULL
하면 내가 원하는 것을 정확하게 수행합니다! "