Kapan menggunakan NULL dan kapan menggunakan string kosong?

82

Saya tertarik terutama pada MySQL dan PostgreSQL, tetapi Anda dapat menjawab yang berikut secara umum:

  • Apakah ada skenario logis yang akan berguna untuk membedakan string kosong dari NULL?
  • Apa yang akan menjadi implikasi penyimpanan fisik untuk menyimpan string kosong sebagai ...

    • BATAL?
    • String Kosong?
    • Bidang lain?
    • Ada cara lain?
Maniero
sumber

Jawaban:

67

Katakanlah catatan tersebut berasal dari formulir untuk mengumpulkan informasi nama dan alamat. Baris 2 dari alamat biasanya akan kosong jika pengguna tidak tinggal di apartemen. String kosong dalam kasus ini sangat valid. Saya cenderung lebih suka menggunakan NULL berarti bahwa nilainya tidak diketahui atau tidak diberikan.

Saya tidak percaya perbedaan penyimpanan fisik layak dikhawatirkan dalam praktiknya. Sebagai administrator basis data, kami memiliki ikan yang jauh lebih besar untuk digoreng!

Larry Coleman
sumber
2
+1 sangat sedikit dba yang perlu khawatir tentang perbedaan kecepatan / ukuran menggunakan NULLatau tidak
Patrick
28
Setuju ... Saya mencoba memesan NULL untuk 'tidak dikenal' ... string kosong adalah 'kita tahu itu harus kosong'. Ini sangat berguna ketika data Anda berasal dari berbagai sumber
Joe
6
Luar Biasa - NULL tidak dikenal, String Kosong ditentukan.
ScottCher
@Larry apa dampak kinerja? Bagaimana kinerja bervariasi dengan tabel banyak cols vs tabel banyak baris?
Shimmy
Saya setuju bahwa jika ada perbedaan antara tidak ada nilai yang diberikan dan string kosong dalam dataset Anda maka Anda harus menggunakannya secara tepat, tetapi secara pribadi jika saya tidak memerlukan perbedaan itu dengan data saya maka saya selalu menggunakan string kosong, murni karena saya menemukan bahwa hasil kueri dari klien MySQL pada baris perintah bisa lebih bersih untuk dilihat dengan string kosong daripada banyak NULLs
RTF
25

Saya tidak tahu tentang MySQL dan PostgreSQL, tetapi biarkan saya memperlakukan ini secara umum.

Ada satu DBMS yaitu Oracle yang tidak memungkinkan untuk memilih pengguna antara NULL dan ''. Ini jelas menunjukkan bahwa tidak perlu untuk membedakan keduanya. Ada beberapa konsekuensi yang menjengkelkan:

Anda mengatur varchar2 ke string kosong seperti ini:

Update mytable set varchar_col = '';

berikut ini mengarah pada hasil yang sama

Update mytable set varchar_col = NULL;

Tetapi untuk memilih kolom di mana nilainya kosong atau NULL, Anda harus menggunakan

select * from mytable where varchar_col is NULL;

Menggunakan

select * from mytable where varchar_col = '';

secara sintaksis benar, tetapi tidak pernah mengembalikan baris.

Di sisi lain, ketika merangkai string di Oracle. NULL varchars diperlakukan sebagai string kosong.

select NULL || 'abc' from DUAL;

hasil abc . DBMS lain akan mengembalikan NULL dalam kasus ini.

Ketika Anda ingin mengekspresikan secara eksplisit, bahwa suatu nilai diberikan, Anda harus menggunakan sesuatu seperti ''.

Dan Anda harus khawatir apakah memangkas tidak menghasilkan kosong di NULL

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

Itu benar.

Sekarang melihat DBMS di mana '' tidak identik dengan NULL (mis. SQL-Server)

Bekerja dengan '' umumnya lebih mudah dan dalam kebanyakan kasus tidak ada kebutuhan praktis untuk membedakan keduanya. Salah satu pengecualian yang saya tahu, adalah ketika kolom Anda mewakili beberapa pengaturan dan Anda belum mengosongkan default untuk mereka. Saat Anda dapat membedakan antara '' dan NULL, Anda dapat menyatakan bahwa pengaturan Anda kosong dan menghindari penerapan default.

bernd_k
sumber
17

Itu tergantung pada domain yang sedang Anda kerjakan. NULLberarti tidak adanya nilai (yaitu tidak ada nilai ), sedangkan string kosong berarti ada nilai string dengan panjang nol.

Misalnya, Anda memiliki tabel untuk menyimpan data seseorang dan itu berisi Genderkolom. Anda dapat menyimpan nilai sebagai 'Pria' atau 'Wanita'. Jika pengguna dapat memilih untuk tidak memberikan data gender, Anda harus menyimpannya sebagai NULL(yaitu pengguna tidak memberikan nilai) dan bukan mengosongkan string (karena tidak ada gender dengan nilai '').

Gan
sumber
7
Jika pengguna memilih untuk tidak menyediakan gender, tentunya Anda harus menyimpan "Ditolak untuk menyediakan". NULL bersifat mendua; itu juga bisa berarti "pelanggan belum diminta", "pelanggan mengidentifikasi dengan jenis kelamin yang tidak ada dalam daftar kami", dll.
Jon of All Trades
9

Satu hal yang perlu diingat adalah bahwa ketika Anda memiliki bidang yang tidak diperlukan, tetapi nilai apa pun yang ada harus unik akan mengharuskan Anda untuk menyimpan nilai kosong sebagai NULL. Jika tidak, Anda hanya akan dapat memiliki satu tuple dengan nilai kosong di bidang itu.

Ada juga beberapa perbedaan dengan aljabar relasional dan nilai NULL: NULL! = NULL, misalnya.

Matthew Schinckel
sumber
4
Sebenarnya bukan NULL! = NULL, karena itu NULL. ;-)
Peter Eisentraut
1
Perhatikan bahwa MS SQL tidak mengikuti aturan ini: beberapa nilai NULL akan melanggar UNIQUEbatasan. Untungnya, mulai tahun 2008 Anda dapat menggunakan indeks yang difilter untuk mendapatkan perilaku yang tepat.
Jon dari Semua Perdagangan
4

Sebuah pikiran baru, pengaruh besar pada pilihan Anda NULL/ NOT NULLadalah jika Anda menggunakan kerangka. Saya menggunakan banyak symfony dan menggunakan NULLbidang yang memungkinkan menyederhanakan beberapa kode dan memeriksa data ketika memanipulasi data.

Jika Anda tidak menggunakan kerangka kerja atau jika Anda menggunakan pernyataan dan pemrosesan sql sederhana, saya akan memilih mana saja yang Anda rasa lebih mudah untuk dilacak. Saya biasanya lebih suka NULL sehingga melakukan INSERTpernyataan tidak membosankan dengan lupa mengatur bidang kosong NULL.

Patrick
sumber
pertanyaannya adalah tentang NULL vs string kosong (dalam kolom nullable, IMO), bukan NULL vs NOT NULL, bukan?
Gan
bagian dari pertanyaan yang diajukan tentang penyimpanan membuat saya berpikir bahwa dia mungkin juga memikirkan Null / Tidak Null
Patrick
atau @ semua orang lain mengenai implikasi NULL vs NOT NULL, Anda dapat merujuk ini: dba.stackexchange.com/q/63/107
Gan
2

Setelah harus bekerja dengan Oracle ( yang tidak memungkinkan Anda untuk membedakan ) saya sampai pada kesimpulan berikut:

  • Dari POV logis tidak masalah. Saya benar-benar tidak bisa memikirkan contoh menarik di mana membedakan antara NULL dan nol-panjang-string menambahkan nilai apa pun di DBMS.

  • Dari yang berikut: Anda juga memiliki NULLkolom mampu yang tidak mengizinkan zero-len ''(solusi Oracle-ish) atau NOT NULLkolom yang memungkinkan zero-len.

  • Dan dari pengalaman saya, ''membuat banyak lebih masuk akal ketika memproses data, seperti yang biasanya Anda ingin memproses tanpa adanya string sebagai string kosong: Penggabungan, Perbandingan, dll

Catatan: Untuk kembali ke pengalaman Oracle saya: Katakan Anda ingin membuat permintaan untuk permintaan pencarian. Jika Anda menggunakan, ''Anda bisa menghasilkan WHERE columnX = <searchvalue>dan itu akan bekerja untuk pencarian kesetaraan. Jika Anda menggunakan NULLyang harus Anda lakukan WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)

Martin
sumber
2

Mereka juga berbeda dari perspektif desain:

misalnya

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

CREATE UNIQUE INDEX t_AK1 ON t (name);

Seperti:

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

Mari kita memasukkan beberapa data:

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"

Sekarang mari kita coba dengan nol:

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

INSERT 0 1

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

INSERT 0 1

Ini dibolehkan

Soooooo: nulls bukan string sepele atau sebaliknya.

Tepuk tangan

Guy Birkbeck
sumber
1

Jika kita berbicara tentang teori, maka aturan Codd mengatakan bahwa RDBMS harus memperlakukan NULLnilai dengan cara khusus.

Bagaimana tepatnya yang digunakan tergantung pada arsitek basis data, tergantung pada domain aktual - tugas - proyek - aplikasi - area.

noonex
sumber