와우, 정답은 "성능을 저하시키기 때문에 NULL을 허용하지 않을 때"를 허용하는 것입니다. 나는 그것을 찬성하고 정교하게 할 것이다. RDBMS가 스파 스가 아닌 열에 대해 NULL을 허용하면 해당 열은 각 개별 행에 대해 값이 NULL인지 여부를 추적하는 비트 맵에 추가됩니다. 따라서 모든 열이 NULL을 허용하지 않는 테이블의 열에 NULL 기능을 추가하면 테이블을 저장하는 데 필요한 저장 공간이 늘어납니다. 또한 RDBMS가 비트 맵을 읽고 쓰도록 요구하므로 모든 작업의 성능이 저하됩니다.
또한 많은 경우 NULL을 허용하면 3NF가 중단됩니다. 나는 많은 동료들처럼 3NF를 고집하지는 않지만 다음 시나리오를 고려하십시오.
Person 테이블에는 DateOfDeath라는 열이 있으며이 열은 Null을 허용합니다. 사람이 사망 한 경우 DateOfDeath로 채워지며 그렇지 않으면 NULL로 남습니다. IsAlive라는 Null을 허용하지 않는 비트 열도 있습니다. 이 열은 사람이 살아있는 경우 1로 설정되고 사람이 죽은 경우 0으로 설정됩니다. 대부분의 저장 프로시 저는 IsAlive 열을 사용하며 DateOfDeath가 아닌 사람이 살아있는 경우에만 관심을 갖습니다.
그러나 IsAlive 열은 DateOfDeath에서 완전히 파생되므로 데이터베이스 정규화가 중단됩니다. 그러나 IsAlive는 대부분의 SP에 연결되어 있기 때문에 간단한 해결책은 DateOfDeath를 Null을 허용하지 않도록 설정하고 사람이 아직 살아있는 경우 열에 기본값을 할당하는 것입니다. 그런 다음 DateOfDeath를 사용하는 소수의 SP를 다시 작성하여 IsAlive 열을 확인하고 사람이 살아 있지 않은 경우에만 DateOfDeath를 적용 할 수 있습니다. 다시 말하지만, 대부분의 SP는이 패턴을 사용하는 DateOfDeath (날짜)가 아닌 IsAlive (비트)에만 관심이 있기 때문에 액세스 속도가 상당히 빨라집니다.
모든 스키마에서 NULL이없는 널 입력 가능 컬럼을 찾는 데 유용한 T-SQL 스크립트는 다음과 같습니다.
select 'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' WHERE ' + QUOTENAME(c.name) + ' IS NULL)
AND (SELECT COUNT(*) FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ') > 1 PRINT ''' + s.name + '.' + t.name + '.' + REPLACE(c.name, '''', '''''') + ''''
from sys.columns c
inner join sys.tables t ON c.object_id = t.object_id
inner join sys.schemas s ON s.schema_id = t.schema_id
where c.is_nullable = 1 AND c.is_computed = 0
order by s.name, t.name, c.name;
프로덕션 데이터베이스의 사본에서 이것을 실행하면 실제로 NULL이없는 NULL을 허용하는 것으로 표시된 열 개발자를 찾을 수 있습니다. 이들 대부분은 NOT NULL로 표시 될 수 있으므로 성능이 향상되고 저장 공간이 줄어 듭니다.
모든 테이블에서 모든 NULL을 제거하는 것이 가능하지는 않지만 여전히 깔끔한 디자인을 가지고 있지만 가능한 많은 NULL을 제거하면 상당한 이점이 있습니다. 옵티마이 저는이 정보로 훨씬 빠르게 작동하며 테이블에서 모든 NULL을 제거 할 수 있으면 상당한 양의 스토리지 공간을 다시 확보 할 수 있습니다.
나는 DBA가 생각하는 성능이 그다지 중요하지 않다는 것을 알고 있지만 솔루션에서 제한된 양의 메모리와 프로세서 파워 만 던질 수 있습니다. .
또한 이것은 실제 RDBMS에만 해당되며 SQL Server에서 답변의 기술적 부분을 기반으로합니다. Null이없는 Null 허용 열을 찾기위한 나열된 T-SQL도 SQL Server에서 가져 왔습니다.