MySQL, NULL 또는 빈 문자열을 삽입하는 것이 더 낫습니까?


230

웹 사이트에 다양한 입력란이있는 양식이 있습니다. 일부 필드는 선택 사항이지만 일부 필드는 필수입니다. 내 DB에는 이러한 모든 값을 보유하는 테이블이 있습니다. 사용자가 데이터를 넣지 않은 DB 열에 NULL 값 또는 빈 문자열을 삽입하는 것이 더 나은 방법입니까?

답변:


220

사용하여 NULL당신이 구별 할 수 "데이터를 넣어 없다"와 "빈 데이터를 넣어".

더 많은 차이점 :

  • LENGTHNULL이며 NULL, LENGTH빈 문자열은 0입니다.

  • NULL빈 문자열보다 먼저 정렬됩니다.

  • COUNT(message)빈 문자열을 계산하지만 NULLs 는 계산하지 않습니다.

  • 바운드 변수를 사용하여 빈 문자열을 검색 할 수 있지만을 검색 할 수는 없습니다 NULL. 이 쿼리는

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?

    클라이언트에서 전달한 값이 무엇이든 NULLin 과 일치하지 않습니다 mytext. 를 일치 시키려면 NULL다른 쿼리를 사용해야합니다.

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL

3
그러나 어느 쪽이 더 빠르다고 생각합니까? 0 또는 NULL 또는 ""
Atul Dravid

8
InnoDB NULL에서 공간을 덜 차지
Timo Huovinen

37
나는 이것이 정답이라고 생각하지만 질문의 "모범 사례"요소를 완전히 무시하고 접선 적으로 관련된 사실에만 초점을 맞 춥니 다 (NULL 정렬 순서 및 길이? 이것은 중요하지 않습니다). 대부분의 텍스트 데이터 입력 유형에는 "응답 없음"과 "빈 응답"간에 차이 가 없으므로 더 나은 답변이 필요한 훌륭한 질문이라고 생각합니다.
Nick

6
UNIQUE 필드가 설정되면 NULL도 훌륭하게 작동합니다. 예를 들어 운전 면허증과 같은 필드에 개인의 DL 번호를 추가하고 그 사람이없는 경우. 이 필드는 고유 필드이므로 DL 번호가없는 첫 번째 사용자는 추가되지만 고유 제한 조건의 오류가 발생하므로 다음 사용자는 추가되지 않습니다. 따라서 NULL이 더 좋습니다.
Saifur Rahman Mohsin

1
@Quassnoi 아 죄송합니다 ... 왜 운전 번호 라이센스를 고유하게 설정하는 것이 나쁜 습관입니까?
cedbeu 2016 년

44

당신이 경우 고려해야 할 한 가지는 지금까지 데이터베이스를 전환 계획이 있다는 것입니다 오라클은 빈 문자열을 지원하지 않습니다 . 그것들은 자동으로 NULL로 변환되며 같은 절을 사용하여 쿼리 할 수 ​​없습니다 WHERE somefield = ''.


11
이 링크 에서조차도 엄청나게 비린내 들려서 시도했습니다. 널 필드, ''로 설정하면 oracle은이를 무시합니다. 길이를 0이 아닌 null로보고합니다. 너무 잘못되었습니다. 이 문제를 해결할 방법이 있습니다. 이 질문을 다른 질문으로 게시하겠습니다.
Steve B.

1
Steve B.:이 질문을보십시오 : stackoverflow.com/questions/1171196/…
Quassnoi

나는 여전히 추론을 이해하지 못하지만 참조 해 주셔서 감사합니다. 으로 게시 stackoverflow.com/questions/1268177/...
스티브 B.

가치의 링크 정보를 포함하는 답을 업데이트가 Quassnoi에 의해 게시 될 수 있습니다
SamuelKDavis

7
Peoplesoft (Oracle DB 포함)는 단일 공백을 사용하여 빈 값을 나타냅니다. 엄청 바보입니다. 또한 0을 사용할 수 없으므로 0.00025를 사용하여 FTE에 0을 나타냅니다. 그 제품에서 사랑스러운 선택이 이루어졌습니다.
JP Duffy

9

명심해야 할 한 가지는 NULL이 코드 경로를 훨씬 더 어렵게 만들 수 있다는 것입니다. 예를 들어 Python에서는 대부분의 데이터베이스 어댑터 / ORM이에 매핑 NULL됩니다 None.

따라서 다음과 같은 것들이 있습니다.

print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow

"안녕하세요, Joe Doe!" 이를 피하려면 다음 코드가 필요합니다.

if databaserow.title:
    print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
    print "Hello, %(firstname) %(lastname)!" % databaserow

훨씬 복잡한 작업을 수행 할 수 있습니다.


25
제 생각에는 코드 또는 프레임 워크의 오류를 "수정"하기 위해 데이터베이스를 남용하는 것은 (매우) 나쁜 코딩 방식입니다. 데이터가 없으면 NULL을 삽입하고 일관성있게 사용해야합니다. 그렇지 않으면 if (myString == null || myString = "")와 같은 명령문을 사용해야합니다. 코드에 객체가 설정되거나 정의되어 있지 않으면 일종의 "자리 표시 자"(빈 문자열이 내 의견으로는) 대신 NULL을 사용하고 있습니다.
Gertjan

5
선택한 언어에 따라 크게 다릅니다. 파이썬에서 "if not myString :"은 None과 ""를 테스트합니다. 아마도 주로 문화 문제입니다. Java Guys "나쁜 습관"은 역동적 인 사람의 우아함입니다.
최대

9

NULLMySQL의 데이터베이스 일관성을 위해 삽입 하는 것이 좋습니다. 외래 키는 NULL빈 문자열로 저장 될 수 있지만 빈 문자열로 저장 될 수는 없습니다.

제약 조건에 빈 문자열 이있는 문제가 있습니다 . 외래 키 제약 조건을 충족시키기 위해 고유 한 빈 문자열 로 가짜 레코드를 삽입해야 할 수도 있습니다 . 나쁜 습관이라고 생각합니다.

참고 : 외래 키가 NULL이거나 중복 될 수 있습니까?


제약 문제는 과거에 저를 넘어서서이 답변을 "+1"하는 이유입니다.
HPWD

그러나 NULL을 사용하면 빈 문자열로 끝나지 않아야합니다. 많은 UI 기술로 쉽게 할 수 있습니다.
Tuntable

5

나는 최선의 방법이 무엇인지 알지 못하지만 null이 빈 문자열과 다른 것을 의미하지 않고 사용자의 입력이 빈 문자열 정의와 일치하지 않는 한 일반적으로 null을 선호합니다.

나는 그들이 당신이 어떻게 다른지를 원하는지 정의해야한다고 말하고 있습니다. 때로는 그것들을 다르게하는 것이 합리적이며 때로는 그렇지 않습니다. 그렇지 않다면, 하나만 골라 붙입니다. 내가 말했듯이, 나는 대부분 NULL을 선호하는 경향이 있습니다.

열이 널 (null) 인 경우 널 (null) 열에 대한 선택이 아닌 한 해당 열을 기반으로 선택하는 (SQL 용어에 where 절이있는) 모든 쿼리에 레코드가 거의 나타나지 않을 것임을 명심하십시오. 물론이야.


1
... 그리고 지금 위의 대답을 보았으므로, 당신이 관심을 가질 일반적인 차이점은 데이터와 빈 데이터가 아니라고 말하는 것이 안전하다고 생각합니다. :-)
Platinum Azure

1

고유 인덱스에서 여러 열을 사용하고 있고 이러한 열 중 하나 이상이 필수 (예 : 필수 양식 필드) 인 경우 인덱스의 다른 열을 NULL로 설정하면 중복 된 행이 생길 수 있습니다. 고유 한 열에서는 NULL 값이 무시되기 때문입니다. 이 경우 중복 된 행을 피하려면 고유 인덱스의 다른 열에 빈 문자열을 사용하십시오.

고유 인덱스의 열 :
(event_type_id, event_title, 날짜, 위치, URL)

실시 예 1 :
(1, 'BBQ', '2018-07-27', null, null)
(1, 'BBQ', '2018-07-27', null, null) // 허용 및 복제

예 2 :
(1, 'BBQ', '2018-07-27', '', '')
(1, 'BBQ', '2018-07-27', '', '') // 중복되므로 허용되지 않습니다.

다음은 몇 가지 코드입니다.

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `event_title` varchar(50) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  `url` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `event_id` (`event_id`,`event_title`,`date`,`location`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

이제 이것을 삽입하여 복제 된 행이 허용되는지 확인하십시오.

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

이제 이것을 삽입하고 허용되지 않는지 확인하십시오.

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

따라서 여기에는 옳고 그름이 없습니다. 비즈니스 규칙에 가장 적합한 것을 결정하는 것은 사용자의 몫입니다.

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