NULL di SQL Itu Aneh
(jirevwe.github.io)-
Di SQL, nilai NULL ditangani secara unik. Kolom dengan batasan UNIQUE dapat memiliki beberapa nilai NULL.
- Ini karena setiap nilai NULL dianggap sebagai nilai independen yang berbeda dari NULL lainnya
- SQLite, Postgres, dan MySQL semuanya berperilaku sama.
-
Menetapkan dasar
select '' = ''; -- Returns 1 (true) string kosong itu sama select 1 = 1; -- Returns 1 (true) angka sama select 1 = 0; -- Returns 0 (false) angka berbeda select null = null; -- Returns NULL (null) huh?- Ini karena NULL adalah placeholder yang merepresentasikan "nilai yang tidak diketahui", sehingga dua nilai yang tidak diketahui tidak dianggap sama
- Dengan menggunakan operator
IS, kita bisa memeriksa identitas NULL. Misalnya,null is nullmengembalikan TRUE.
-
Tentang keunikan
- Jika kolom dengan batasan UNIQUE berisi nilai NULL, nilai-nilai NULL dianggap berbeda satu sama lain sehingga tidak melanggar batasan keunikan.
- Misalnya,
('ray@mail.com', NULL)dan('ray@mail.com', NULL)dianggap sebagai baris yang berbeda.
-
Mengapa NULL diperlakukan seperti ini
- SQLite dan database lain yang kompatibel dengan SQL diimplementasikan seperti ini agar penanganan NULL konsisten dengan database lain. Dokumen standar SQL menyarankan agar NULL harus unik di semua tempat, tetapi pada praktiknya sebagian besar mesin SQL tidak memperlakukan NULL sebagai unik dalam SELECT DISTINCT atau UNION.
-
Cara menjamin keunikan
-
Menggunakan generated column
- Masalah ini bisa dikurangi dengan membuat kolom yang selalu memiliki nilai deterministik yang bukan NULL. Misalnya, Anda bisa menggunakan
COALESCE(deleted_at, '1970-01-01')untuk menggantikan nilai NULL. - Metode ini dapat menambah field pada tabel dan memakan ruang.
- Masalah ini bisa dikurangi dengan membuat kolom yang selalu memiliki nilai deterministik yang bukan NULL. Misalnya, Anda bisa menggunakan
-
Menggunakan partial index
- Anda dapat menjamin keunikan dengan membuat partial index untuk
emailhanya saatdeleted_atbernilai NULL. - Partial index tidak memperlebar tabel, menggunakan ruang lebih sedikit, dan tidak menimbulkan error saat pasangan record yang sama dihapus berulang kali.
- Anda dapat menjamin keunikan dengan membuat partial index untuk
-
-
Pembaruan
- Oracle memperlakukan string kosong sebagai NULL.
-
Kesimpulan
- Saat menggunakan ORM hal ini tidak terlihat, tetapi cara unik SQL menangani NULL dapat menimbulkan kebingungan. Dokumen standar SQL tidak tersedia secara terbuka dan hanya bisa diperoleh dengan membayar.
2 komentar
Semua
nullmemang aneh.Jadi
nulldi SQL yang sebenarnya baik-baik saja malah terlihat aneh…Di negeri orang bermata satu, yang bermata dua justru dianggap tidak normal…
Komentar Hacker News
NULLdi SQL didasarkan pada logika TRUE-FALSE-UNKNOWN milik Kleene. JikaNULLdibaca sebagai UNKNOWN, banyak operasi menjadi lebih mudah dipahami secara intuitifNULLadalah penanda untuk merepresentasikan UNKNOWN, dan duaNULLtidak bisa dikatakan samaNULLS NOT DISTINCTKetika konsep
NULLdiperkenalkan pada tahun 1970-an, sudah terpikir bahwa ini akan menimbulkan banyak kebingungan di masa depan. Setelah 45 tahun berlalu, hal ini masih terus diperdebatkanPemahaman intuitif tentang
NULL: nilaiNULLpada sel tabel tertentu adalah cara untuk menyatakan 'tidak ada nilai'. Saat menginginkan nilai yang unik, kasus ketika tidak ada nilai seharusnya tidak ikut diperhitungkanSkeptisisme terhadap penggunaan ORM: ORM memang praktis, tetapi juga melahirkan generasi yang tidak belajar bagaimana database relasional benar-benar bekerja. Perilaku
NULLdi SQL konsisten dengan aljabar relasional dasar, dan yang bermasalah justruNULLbergaya CMengingat humor tentang perbandingan
NULLdari dialog dalam episode BlackadderDi Oracle, terasa aneh bahwa
NULLdianggap sama dengan string kosongDalam konteks berorientasi objek, "null" berguna untuk menyatakan bahwa atribut tertentu tidak memiliki nilai. Di JavaScript ada
nulldanundefined;undefinedbisa dianggap berarti nilainya tidak diketahui, sedangkannullberarti tidak ada nilaiNULLtidak aneh dalam arti tidak ada duplikasi. KarenaNULLtidak sama satu sama lain, maka tidak bisa dianggap duplikat. Jika tidak menyukai semantikNULL, nilai sentinel bisa digunakanNULLdi SQL tidak aneh jika mempertimbangkan bagaimana logika relasional diharapkan bekerja pada record yang memiliki nilai yang tidak ada