NULL ne zaman ve ne zaman boş bir dize kullanılır?


82

Genelde MySQL ve PostgreSQL ile ilgileniyorum, ancak genel olarak aşağıdakilere cevap verebilirsiniz:

  • Boş bir dizgiyi NULL'dan ayırmanın faydalı olacağı mantıklı bir senaryo var mı?
  • Boş bir dize olarak saklamak için fiziksel depolama etkileri ne olurdu ...

    • BOŞ?
    • Boş Dize?
    • Başka bir alan mı?
    • Başka yol var mı?

Yanıtlar:


67

Diyelim ki bu kayıt isim ve adres bilgilerini toplamak için bir formdan geliyor. Adresin 2. satırı, kullanıcı dairede yaşamadığında genellikle boştur. Bu durumda boş bir dize tamamen geçerlidir. Değerin bilinmediğini veya verilmediğini söylemek için NULL kullanmayı tercih ediyorum.

Fiziksel depolama farkının pratikte endişelenmeye değer olduğuna inanmıyorum. Veri tabanı yöneticileri olarak, kızartılacak daha büyük balıklarımız var!


2
+1 çok az dba, kullanma hızı / büyüklüğü farklılıklarından endişe duymaya ihtiyaç NULLduymuyor
Patrick

28
Anlaştık ... 'bilinmeyen' ... 'boş dizgi' boş olması gerektiğini biliyoruz 'için NULL ayırmaya çalışıyorum. Verileriniz birden fazla kaynaktan geldiğinde özellikle yararlıdır
Joe

6
Üstün - NULL bilinmiyor, Boş Dize belirtildi.
ScottCher

@Larry Performansın etkisi nedir? Performans, birçok satırın tabloları ile birçok satırın tabloları arasında nasıl değişir?
Shimmy

Veri setinizde verilen hiçbir değer ile boş bir dize arasında bir ayrım varsa, bunları uygun şekilde kullanmanız gerektiğini, ancak kişisel olarak verilerimle bu farklılığa ihtiyacım olmadığında, o zaman daima boş bir dize kullanmam gerektiğini kabul ediyorum, çünkü sadece Komut satırındaki bir MySQL istemcisinin bu sorgu sonucunu, NULL'lar yerine boş dizelerle bakmak daha temiz bulabilir
RTF

25

MySQL ve PostgreSQL hakkında hiçbir şey bilmiyorum, ama genel olarak bu biraz tedavi edeyim.

NULL ile '' arasında kullanıcıları seçmesine izin vermeyen Oracle adlı bir DBMS var. Bu açıkça her ikisini birbirinden ayırmanın gerekli olmadığını göstermektedir. Bazı can sıkıcı sonuçlar var:

Varchar2'yi bu gibi boş bir dizeye ayarladınız:

Update mytable set varchar_col = '';

Aşağıdaki aynı sonuç yol açar

Update mytable set varchar_col = NULL;

Ancak değerin boş veya NULL olduğu sütunları seçmek için kullanmanız gerekir.

select * from mytable where varchar_col is NULL;

kullanma

select * from mytable where varchar_col = '';

sözdizimsel olarak doğrudur, ancak hiçbir zaman bir satır döndürmez.

Öte yandan, Oracle'da dizeleri birleştirirken. NULL varchars boş dizge olarak kabul edilir.

select NULL || 'abc' from DUAL;

abc verir . Diğer DBMS bu durumlarda NULL döndürür.

Açıkça ifade etmek istediğinizde, bir değer atandığını, '' gibi bir şey kullanmanız gerekir.

Ve NULL’da kırpmanın boş değil sonuçlandığından endişelenmelisiniz

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

Öyle.

Şimdi '' NULL ile aynı olmayan DBMS'ye bakıyoruz (örneğin, SQL-Server)

'' İle çalışmak genellikle daha kolaydır ve çoğu durumda her ikisini de ayırt etmek için pratik bir ihtiyaç yoktur. Bildiğim istisnalardan biri, sütununuzun bazı ayarları temsil ettiği ve onlar için boş varsayılanları olmadığı zamandır. '' İle NULL arasında ayrım yapabiliyorsanız, ayarınızın boş olduğunu ifade edebilir ve varsayılanın uygulanmasını önleyebilirsiniz.



17

Üzerinde çalıştığınız etki alanına göre değişir. NULLdeğerin yokluğu (yani değer yok ), boş dizge ise sıfır uzunluklu bir dizge olduğu anlamına gelir .

Örneğin, bir kişinin verilerini depolamak için bir tablonuz olduğunu ve bir Gendersütun içerdiğini söyleyin . Değerleri 'Erkek' veya 'Kadın' olarak kaydedebilirsiniz. Kullanıcı cinsiyet verilerini vermemeyi tercih edebilir ise, olarak, kendi etmelidir NULLve (yani kullanıcı değeri vermedi) değil (değerle cinsiyet '' olmadığı için) boş bir dize.


7
Kullanıcı bir cinsiyet belirtmemeyi seçerse, kesinlikle "Vermeyi reddet" seçeneğini kaydetmelisiniz. NULL belirsiz; o da "müşteri talebinde bulunulmadığını" anlamına gelebilir, vb "müşteri değil listemize bir cinsiyet tanımlayan"
Tüm Esnaf ve Jon

8

Akılda tutulması gereken bir şey, gerekli olmayan bir alana sahip olduğunuzda, ancak mevcut herhangi bir değerin benzersiz olması gerektiği, boş değerleri NULL olarak saklamanızı gerektireceğidir. Aksi takdirde, bu alanda yalnızca boş bir değere sahip bir demet elde edebilirsiniz.

Örneğin ilişkisel cebir ve NULL değerlerinde de bazı farklılıklar vardır: Örneğin NULL! = NULL.


4
Aslında NULL değil! = NULL, çünkü NULL. ;-)
Peter Eisentraut

1
MS SQL’in bu kurala uymadığını unutmayın: birden fazla NULL değer bir UNIQUEkısıtlamayı ihlal edecektir . Neyse ki, 2008'den başlayarak uygun davranışı elde etmek için filtrelenmiş bir indeks kullanabilirsiniz.
Tüm İşlemlerden Jon,


4

Yeni bir düşünce, seçiminizi büyük bir etkisi NULL/ NOT NULLbir çerçeve kullanıyorsanız. Symfony çok kullanırım ve izin veren NULLalanları kullanmak , verileri işlerken bazı kod ve veri kontrolünü kolaylaştırır.

Bir çerçeve kullanmıyorsanız veya basit sql deyimlerini ve işlemlerini kullanıyorsanız, takip etmesi daha kolay olduğunu düşündüğünüz seçeneklerden birini tercih ediyorum. Genel olarak NULL tercih ederim, böylece INSERTifadeler yapmak boş alanları ayarlamayı unutmaktan sıkılmaz NULL.


soru NULL'a karşılık boş dizgeye (boş bir sütunda, IMO'ya) ilişkin, NULL'a karşı değil NOT NULL'a değil mi?
Gan

depolama hakkında soru sormak, beni de Null / Null hakkında düşünebileceğini düşünmeme neden oldu
Patrick

veya @ NULL ile NOT NULL'in ima edilmesine ilişkin başka herhangi bir kimse, buna başvurabilirsiniz: dba.stackexchange.com/q/63/107
Gan

2

Oracle ile çalışmak zorunda kaldım ( farklılaşmanıza izin vermez ) Şu sonuca vardım:

  • Mantıksal bir POV'dan farketmez. Gerçekten NULL ile sıfır uzunluklu dize arasındaki farklılığın DBMS'de herhangi bir değer kattığı çekici bir örnek düşünemiyorum.

  • Bundan sonra: NULLSıfır-len'e izin vermeyen bir sütuna ''(Oracle-ish çözümü) veya NOT NULLsıfır-len'e izin veren bir sütuna sahipsiniz.

  • Ve benim deneyim, ''yapar çok Birleştirme, Karşılaştırma, vs, bunlar boş dize olarak bir dize yokluğunu işlemek istiyorum normalde olduğu gibi, veri işlerken daha mantıklı

Not: Oracle deneyimime geri dönmek için: Bir arama isteği için bir sorgu oluşturmak istediğinizi söyleyin. Kullanırsanız ''sadece üretebilir WHERE columnX = <searchvalue>ve eşitlik aramaları için çalışacaktır. Eğer kullanırsan NULLyapmalısın WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)


2

Ayrıca tasarım açısından farklıdırlar:

Örneğin

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

CREATE UNIQUE INDEX t_AK1 ON t (name);

Şuna benziyor:

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

Bazı verileri ekleyelim:

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"

Şimdi null ile deneyelim:

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

INSERT 0 1

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

INSERT 0 1

Buna izin var.

Soooooo: null değerleri önemsiz karakter dizileri ve tersi değildir.

Şerefe


1

Teori hakkında konuşursak, Kod'un kuralları, RDBMS'nin NULLdeğerleri özel bir şekilde ele alması gerektiğini söyler .

Tam olarak nasıl kullanıldığı, etki alanı - görev - proje - uygulama - alanına bağlı olarak veritabanı mimarlarına bağlıdır.

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.