MySQL, NULL veya boş dize eklemek daha iyi?


230

Bir web sitesinde çok farklı alanları olan bir formum var. Alanların bazıları isteğe bağlı, bazıları zorunludur. Benim DB tüm bu değerleri tutan bir tablo var, kullanıcı herhangi bir veri koymadı DB sütunlarına bir NULL değeri veya boş bir dize eklemek daha iyi bir uygulama var mı?

Yanıtlar:


220

Kullanarak NULL"veri koyma" ve "boş veri koyma" arasında ayrım yapabilirsiniz.

Bazı farklılıklar:

  • A LENGTHof NULLis NULL, a LENGTHboş bir dize 0.

  • NULLs, boş dizelerden önce sıralanır.

  • COUNT(message)boş dizeleri sayar, ancak NULLs

  • Bağlı bir değişken kullanarak boş bir dize arayabilir, ancak bir NULL. Bu sorgu:

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?

    Bir maç asla NULLin mytextistemci geçmesi ne olursa olsun değer. NULLS ile eşleştirmek için başka bir sorgu kullanmanız gerekir:

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL

3
ama hangisinin daha hızlı olduğunu düşünüyorsunuz? 0 veya NULL veya ""
Atul Dravid

8
in Nno's NULL daha az yer kaplıyor
Timo Huovinen

37
Bu iyi bir cevap olduğunu düşünüyorum, ama aynı zamanda sorunun "en iyi uygulama" öğesini tamamen görmezden gelir ve sadece teğetsel olarak ilgili gerçeklere odaklanır (NULL sıralama ve uzunluk? Bunlar önemli değil). Çoğu metin veri girişi türleri üzerinde orada değil bu daha iyi bir cevap hak harika bir soru olduğunu düşünüyorum bu yüzden, "hayır yanıtı" ve "boş yanıt" arasında bir fark.
Nick

6
NULL değerleri UNIQUE alanı ayarlandığında da harika çalışır. Örneğin, kişinin DL No.'sunu eklemek için Ehliyet gibi bir alanınız varsa ve bu alana sahip değilseniz. Benzersiz bir alan olduğundan, DL No.'suz ilk kişi eklenir, ancak bir sonraki kısıtlama benzersiz bir sınırlama hatası atar. NULL daha iyi.
Saifur Rahman Mohsin

1
@Quassnoi ah özür dilerim ... Yani, sürücü numarası lisansını benzersiz olarak ayarlamak neden kötü bir uygulamadır?
cedbeu

44

Eğer varsa, dikkate alınması gereken bir şey hiç veritabanları geçiş planı, yani Oracle boş dizeleri desteklemiyor . Bunlar otomatik olarak NULL değerine dönüştürülür ve bunlar gibi cümleleri kullanarak sorgulayamazsınız WHERE somefield = ''.


11
Bu, bağlantınızda bile bana inanılmaz derecede balık gibi geliyordu, bu yüzden denedim. Boş alan, '' olarak ayarlanmış, oracle bunu yoksayar. Uzunluğu 0 yerine null olarak bildirir. Bu çok yanlış. Bunun etrafında bir yol olmalı. Sanırım bunu başka bir soru olarak göndereceğim.
Steve

1
Steve B.: bu soruya bakın: stackoverflow.com/questions/1171196/…
Quassnoi

Referans için teşekkürler, yine de nedenini anlamıyorum. Olarak gönderildi stackoverflow.com/questions/1268177/…
Steve

Quassnoi
SamuelKDavis

7
Peoplesoft (Oracle DB ile) boş bir değeri belirtmek için tek bir boşluk kullanır. İnanılmaz derecede aptalca. Ayrıca 0'a izin verilmediğinden FTE için 0 belirtmek için 0.00025 kullanırlar. Bu üründe güzel seçimler yapıldı.
JP Duffy

9

Akılda tutulması gereken bir şey, NULL'ın kod yollarınızı çok daha zor hale getirebileceğidir. Python örneğin en veritabanı adaptörler / ORMs haritasına NULLiçin None.

Yani şöyle şeyler:

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

"Merhaba, Hiçbiri Joe Doe!" Bundan kaçınmak için bu kod gibi bir şeye ihtiyacınız var:

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

Bu da işleri daha karmaşık hale getirebilir.


25
Bence veritabanınızı kodunuzdaki veya çerçevedeki hataları düzeltmek için kötüye kullanmak (çok) kötü bir kodlama uygulamasıdır. Veri olmadığında sadece NULL eklemeli ve bunu kullanırken tutarlı olmalısınız. Aksi takdirde: if (myString == null || myString = "") gibi ifadeler kullanmalısınız. Kodunuzda bir nesne ayarlanmadığında veya tanımlanmadığında, bir çeşit "yer tutucu" (boş bir dize bence) yerine NULL kullanıyorsunuzdur.
Gertjan

5
Seçim dilinize çok bağlıdır. Python'da "değilse myString:" None ve "" için testler yapar. Muhtemelen daha çok kültürel konular. Java Guys "kötü uygulama" dinamik kişinin zarafeti.
max

9

NULLMySQL veritabanında tutarlılık için Insert daha iyi . Yabancı anahtarlar NULLboş dize olarak saklanabilir, DEĞİL olarak saklanabilir .

Kısıtlamalarda boş bir dize ile ilgili sorunlarınız olacaktır . Yabancı Anahtar sınırlamasını karşılamak için benzersiz bir boş dizeyle sahte bir kayıt eklemeniz gerekebilir . Kötü uygulama sanırım.

Ayrıca bkz: Yabancı anahtar NULL ve / veya çoğaltılabilir mi?


Kısıtlamalar sorunu geçmişte beni tetikledi, bu yüzden bu cevabı "+ 1'ledim".
HPWD

Ancak NULL kullanırsanız, boş dizelerle de karşılaşmayacağınızdan emin olun. Birçok UI teknolojisi ile kolay.
9'da ayarlanabilir

5

Burada en iyi uygulamanın ne olacağını bilmiyorum, ancak boş dizgiden farklı bir şey anlamına gelmesini istemiyorsanız ve kullanıcının girdisi boş dizgi tanımınızla eşleşmediği sürece genellikle boş değer lehine olurdum.

Söylediklerinizin nasıl farklı olmasını istediğinizi tanımlamanız gerektiğini söylüyorum. Bazen onları farklı kılmak mantıklıdır, bazen de değildir. Değilse, sadece birini seçin ve onunla devam edin. Dediğim gibi, çoğu zaman NULL'u tercih etme eğilimindeyim.

Oh ve sütun boşsa, seçim boş bir sütun için olmadığı sürece kaydın o sütuna dayalı olarak seçili (SQL deyiminde bir where cümlesi vardır) herhangi bir sorguda görünme olasılığının daha düşük olduğunu unutmayın. elbette.


1
... Ve şimdi üstümdeki cevabı gördüğüme göre, umursadığınız olağan farklılaşmanın boş verilere karşı veri olmadığını söylemek güvenli. :-)
Platinum Azure

1

Benzersiz bir dizinde birden çok sütun kullanıyorsanız ve bu sütunlardan en az biri zorunluysa (yani, zorunlu bir form alanı), dizindeki diğer sütunları NULL olarak ayarlarsanız, çoğaltılan satırlarla karşılaşabilirsiniz. Bunun nedeni, NULL değerlerin benzersiz sütunlarda yok sayılmasıdır. Bu durumda, yinelenen satırları önlemek için benzersiz dizinin diğer sütunlarında boş dizeler kullanın.

EŞSİZ BİR DİZİNDE SÜTUNLAR:
(event_type_id, event_title, tarih, konum, url)

ÖRNEK 1:
(1, 'Barbekü', '2018-07-27', boş, boş)
(1, 'Barbekü', '2018-07-27', boş, boş) // izin verildi ve çoğaltıldı.

ÖRNEK 2:
(1, 'Barbekü', '2018-07-27', '', '')
(1, 'Barbekü', '2018-07-27', '', '') // çoğaltıldığı için izin VERİLMEZ.

İşte bazı kodlar:

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;

Şimdi, yinelenen satırlara izin vereceğini görmek için bunu ekleyin:

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);

Şimdi bunu ekleyin ve izin verilmediğini kontrol edin:

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', '', '');

Yani, burada doğru ya da yanlış yoktur. İş kurallarınızda neyin en iyi olduğuna siz karar verirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.