NULL을 언제 사용하고 언제 빈 문자열을 사용합니까?


82

나는 주로 MySQL과 PostgreSQL에 관심이 있지만 일반적으로 다음에 대답 할 수 있습니다.

  • 빈 문자열을 NULL과 구별하는 것이 유용한 논리적 시나리오가 있습니까?
  • 빈 문자열을 다음과 같이 저장하면 실제 저장소에 미치는 영향은 무엇입니까?

    • 없는?
    • 빈 문자열?
    • 다른 분야?
    • 다른 방법?

답변:


67

레코드가 이름과 주소 정보를 수집하는 양식에서 나온다고 가정 해 봅시다. 사용자가 아파트에 거주하지 않는 경우 일반적으로 주소의 2 행은 비어 있습니다. 이 경우 빈 문자열은 완벽하게 유효합니다. 값을 알 수 없거나 제공하지 않았 음을 의미하기 위해 NULL을 사용하는 것을 선호합니다.

실제 스토리지 차이가 ​​실제로 걱정할 가치가 있다고 생각하지 않습니다. 데이터베이스 관리자로서 우리는 더 큰 생선 ​​튀김을 가지고 있습니다!


2
+1 아주 적은 dba가 사용의 속도 / 크기 차이에 대해 걱정할 필요가 NULL없습니다
Patrick

28
합의 ... '알 수 없음'에 대해 NULL을 예약하려고합니다 ... 빈 문자열은 '비어 있어야한다는 것을 알고 있습니다'. 데이터가 여러 소스에서 온 경우 특히 유용합니다
Joe

6
두드러짐-NULL을 알 수 없음, 빈 문자열이 지정되었습니다.
ScottCher

@Larry 성능 영향은 무엇입니까? 열 수가 많은 테이블과 행이 많은 테이블의 성능은 어떻게 다릅니 까?
Shimmy

데이터 세트에 주어진 값과 빈 문자열이 구별되지 않으면 적절하게 사용해야하지만 개인적으로 내 데이터와 구별이 필요하지 않으면 항상 빈 문자열을 사용한다는 데 동의합니다. 명령 행에서 MySQL 클라이언트의 쿼리 결과는 많은 NULL 대신 빈 문자열로보다 깨끗하게 볼 수 있습니다.
RTF

25

MySQL과 PostgreSQL에 대해서는 잘 모르지만 이것을 일반적으로 다루겠습니다.

하나의 DBMS가 있는데, Oracle은 NULL과 ''사이에서 사용자를 선택할 수 없습니다. 이것은 두 가지를 구별 할 필요가 없음을 분명히 보여줍니다. 성가신 결과가 있습니다.

varchar2를 다음과 같이 빈 문자열로 설정합니다.

Update mytable set varchar_col = '';

다음은 동일한 결과로 이어집니다

Update mytable set varchar_col = NULL;

그러나 값이 비어 있거나 NULL 인 열을 선택하려면

select * from mytable where varchar_col is NULL;

사용

select * from mytable where varchar_col = '';

문법적으로 정확하지만 행을 반환하지 않습니다.

반면에 Oracle에서 문자열을 연결할 때. NULL varchar는 빈 문자열로 처리됩니다.

select NULL || 'abc' from DUAL;

abc를 산출 합니다. 이 경우 다른 DBMS는 NULL을 리턴합니다.

명시 적으로 표현하고 싶을 때 값이 할당되면 ''와 같은 것을 사용해야합니다.

그리고 비어 있지 않은 트리밍 결과가 NULL인지 걱정해야합니다.

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

그렇습니다.

이제 ''가 NULL과 동일하지 않은 DBMS를 봅니다 (예 : SQL-Server).

''작업은 일반적으로 더 쉽고 대부분의 경우 두 가지를 구별 할 실질적인 필요가 없습니다. 내가 알고있는 예외 중 하나는 열이 일부 설정을 나타내며 기본값이 비어 있지 않은 경우입니다. ''와 NULL을 구별 할 수 있으면 설정이 비어 있음을 표시하고 기본값이 적용되지 않도록 할 수 있습니다.



17

작업중인 도메인에 따라 다릅니다. NULL는 값이 없음을 의미하고 (즉 , 없음 ) 빈 문자열은 길이가 0 인 문자열 값 을 의미 합니다.

예를 들어 개인의 데이터를 저장하는 테이블이 있고 Gender열 이 포함되어 있다고 가정 합니다. 값을 'Male'또는 'Female'로 저장할 수 있습니다. 사용자가 성별 데이터를 제공하지 않도록 선택할 수 있다면, 당신은 같은 것을 저장해야 NULL하고 (즉, 사용자가 값을 제공하지 않았다) 하지 (값 성별이 '가 없기 때문에) 빈 문자열을.


7
사용자가 성별을 제공하지 않기로 선택한 경우 반드시 "제공을 거부했습니다"를 저장해야합니다. NULL은 모호합니다. 그것은 "고객이 요청받지 않았다", "고객이 우리의 목록에없는 성별로 식별된다"등을 의미 할 수도 있습니다.
모든 거래의 존

8

명심해야 할 점은 필드가 필요하지 않은 경우 존재하는 값은 고유해야하며 빈 값을 NULL로 저장해야한다는 것입니다. 그렇지 않으면 해당 필드에 빈 값을 가진 하나의 튜플 만 가질 수 있습니다.

관계 대수 및 NULL 값과의 차이점도 있습니다. 예를 들어 NULL! = NULL입니다.


4
NULL이기 때문에 실제로 NULL! = NULL 인 경우는 아닙니다. ;-)
Peter Eisentraut

1
MS SQL은이 규칙을 따르지 않습니다. 여러 NULL 값이 UNIQUE제약 조건 을 위반합니다 . 다행히 2008 년부터 필터링 된 인덱스를 사용하여 올바른 동작을 수행 할 수 있습니다.
모든 거래의 존


4

새로운 생각, 당신의 선택에 큰 영향 NULL/는 NOT NULL당신이 프레임 워크를 사용하는 경우입니다. 심포니를 많이 사용하고 허용 NULL필드를 사용 하면 데이터를 조작 할 때 일부 코드 및 데이터 검사가 단순화됩니다.

프레임 워크를 사용하지 않거나 간단한 SQL 문 및 처리를 사용하는 경우 추적하기가 더 쉬운 선택을 할 것입니다. 나는 일반적으로 NULL을 선호하므로 INSERT문을 수행하는 것이 빈 필드를로 설정하는 것을 잊어 버릴 수 있습니다 NULL.


문제는 NULL 대 NOT NULL이 아닌 NULL 대 빈 문자열 (널링 가능 열의 IMO)에 관한 것입니까?
Gan

스토리지에 대한 질문의 일부로 인해 Null / Null이 아닌 것으로 생각하고 있다고 생각하게되었습니다.
Patrick

또는 NULL과 NOT NULL의 의미에 관한 @everyone은 dba.stackexchange.com/q/63/107
Gan

2

오라클과 협력해야 했으므로 ( 차별 할 수 없음 ) 다음 결론에 도달했습니다.

  • 논리적 POV에서는 중요하지 않습니다. NULL과 길이가 0 인 문자열을 구분하여 DBMS에 값을 추가하는 매력적인 예를 생각할 수 없습니다.

  • 다음 중 하나 : NULLzero-len ''(Oracle-ish 솔루션)을 허용하지 않는 NOT NULL열 또는 zero-len을 허용 하는 열이 있습니다.

  • 그리고 내 경험에서, ''많은 병합, 비교 등 : 당신이 빈 문자열로 문자열의 부재를 처리하고 싶습니다 일반적으로, 데이터를 처리 할 때 더 이해

참고 : Oracle 환경으로 돌아가려면 : 검색 요청에 대한 쿼리를 생성한다고 가정하십시오. 사용 ''하면 그냥 생성 할 수 있으며 WHERE columnX = <searchvalue>평등 검색에 작동합니다. 당신이 사용하는 경우 NULL해야 WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL)합니다. 바! :-)


2

또한 디자인 관점과 다릅니다.

예 :

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

다음과 같습니다.

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

일부 데이터를 삽입 할 수 있습니다.

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

이제 null로 시도해보십시오.

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

허용됩니다.

Soooooo : 널은 사소한 문자열도 아니고 그 반대도 아닙니다.

건배


1

우리가 이론에 관해 이야기한다면, Codd의 규칙은 RDBMS가 NULL특별한 방식으로 가치를 다루어야한다고 말합니다 .

실제로 사용되는 방법은 실제 도메인-작업-프로젝트-응용 프로그램-영역에 따라 데이터베이스 설계자에게 달려 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.