Di sini saya mudah-mudahan akan memperjelas posisi saya.
Yang NULL = NULL
mengevaluasi untuk FALSE
salah. Peretas dan Tuan menjawab dengan benar NULL
. Inilah sebabnya. Dewayne Christensen menulis kepada saya, dalam komentar untuk Scott Ivey :
Karena ini bulan Desember, mari kita gunakan contoh musiman. Saya punya dua hadiah di bawah pohon. Sekarang, katakan padaku apakah saya mendapat dua hal yang sama atau tidak.
Mereka bisa berbeda atau mereka bisa sama, Anda tidak tahu sampai seseorang membuka kedua hadiah. Siapa tahu? Anda mengundang dua orang yang tidak mengenal satu sama lain dan keduanya telah melakukan untuk Anda hadiah yang sama - langka, tetapi bukan tidak mungkin § .
Jadi pertanyaannya: apakah kedua UNKNOWN ini menyajikan yang sama (sama, =)? Jawaban yang benar adalah: TIDAK DIKETAHUI (yaitu NULL
).
Contoh ini dimaksudkan untuk menunjukkan bahwa ".. ( false
atau null
, tergantung pada sistem Anda) .." adalah jawaban yang benar - bukan, hanya NULL
benar dalam 3VL (atau apakah Anda dapat menerima sistem yang memberikan jawaban yang salah? )
Jawaban yang benar untuk pertanyaan ini harus menekankan dua poin ini:
- Logika tiga nilai (3VL) adalah berlawanan dengan intuisi (lihat pertanyaan lain yang tak terhitung jumlahnya tentang subjek ini di Stackoverflow dan di forum lain untuk memastikan);
- DBMSes berbasis SQL sering tidak menghargai bahkan 3VL, mereka kadang-kadang memberikan jawaban yang salah (seperti yang dinyatakan oleh poster asli, SQL Server lakukan dalam kasus ini).
Jadi saya ulangi: SQL tidak ada gunanya memaksa orang untuk menafsirkan properti refleksif kesetaraan, yang menyatakan bahwa:
for any x, x = x
§§ (dalam bahasa Inggris yang sederhana: apa pun alam semesta wacana, "sesuatu" selalu sama dengan dirinya sendiri ).
.. dalam 3VL ( TRUE
, FALSE
, NULL
). Harapan orang akan sesuai dengan 2VL ( TRUE
,, FALSE
yang bahkan dalam SQL berlaku untuk semua nilai lainnya), yaitu x = x
selalu dievaluasi untuk TRUE
, untuk setiap kemungkinan nilai x - tanpa pengecualian.
Perhatikan juga bahwa NULL adalah " non-nilai " yang valid (seperti yang dikatakan oleh pembela mereka) yang dapat ditetapkan sebagai nilai atribut (??) sebagai bagian dari variabel relasi. Jadi mereka adalah nilai yang dapat diterima dari setiap jenis (domain), tidak hanya dari jenis ekspresi logis.
Dan ini adalah poin saya : NULL
, sebagai nilai, adalah "binatang aneh". Tanpa eufemisme, saya lebih suka mengatakan: omong kosong .
Saya pikir formulasi ini jauh lebih jelas dan kurang bisa diperdebatkan - maaf atas kemampuan bahasa Inggris saya yang buruk.
Ini hanya salah satu masalah dari NULLs. Lebih baik hindari mereka sepenuhnya, jika memungkinkan.
§ kami prihatin dengan nilai - nilai di sini, sehingga fakta bahwa kedua hadiah selalu dua objek fisik yang berbeda bukanlah keberatan yang valid; jika Anda tidak yakin saya minta maaf, bukankah ini tempat untuk menjelaskan perbedaan antara semantik nilai dan "objek" (Aljabar Relasional memiliki semantik nilai sejak awal - lihat prinsip informasi Codd; Saya pikir beberapa pelaksana DBMS SQL tidak bahkan tidak peduli dengan semantik umum).
§§ pengetahuan saya, ini adalah sebuah aksioma yang diterima (dalam bentuk atau lain, tapi selalu ditafsirkan dalam 2VL a) sejak jaman dahulu dan itu persis karena sangat intuitif. 3VLs (adalah keluarga logika pada kenyataannya) adalah perkembangan yang jauh lebih baru (tapi saya tidak yakin kapan pertama kali dikembangkan).
Catatan: jika seseorang akan memperkenalkan Jenis Bawah , Unit dan Opsi sebagai upaya untuk membenarkan SQL NULLs, saya akan diyakinkan hanya setelah pemeriksaan yang cukup rinci yang akan menunjukkan bagaimana implementasi SQL dengan NULLs memiliki sistem jenis suara dan akan menjelaskan, akhirnya, apa NULLs (ini "nilai-bukan-cukup-nilai") sebenarnya.
Pada bagian selanjutnya saya akan mengutip beberapa penulis. Kesalahan atau kelalaian mungkin milik saya dan bukan dari penulis aslinya.
Joe Celko pada SQL NULLs
Saya melihat Joe Celko sering dikutip di forum ini. Rupanya dia adalah penulis yang sangat dihormati di sini. Jadi, saya berkata pada diri sendiri: "apa yang dia tulis tentang SQL NULL? Bagaimana dia menjelaskan banyak masalah NULL?". Salah satu teman saya memiliki versi ebook SQL Joe Joe untuk kecerdasan: pemrograman SQL tingkat lanjut, edisi ke-3 . Ayo lihat.
Pertama, daftar isi. Hal yang paling mengejutkan saya adalah berapa kali NULL disebutkan dan dalam konteks yang paling beragam:
3.4 Aritmatika dan
NULL 109 3.5 Nilai Konversi ke dan dari NULL 110
3.5.1 NULLIF () Fungsi 110
6 NULL : Data yang Hilang dalam SQL 185
6.4 Membandingkan NULLs 190
6.5 NULLs dan Logic 190
6.5.1 NULLS dalam Predikat Subquery 191
6.5.2 Standar Solusi SQL 193
6.6 Matematika dan NULL 193
6.7 Fungsi dan NULL 193
6.8 NULLs dan Bahasa Host 194
6.9 Nasihat Desain untuk NULLs 195
6.9.1 Menghindari
NULL dari Program Host 197 6.10 Catatan tentang Beberapa Nilai NULL 198
10.1 IS NULL Predikat 241
10.1. 1 Sumber NULLs 242
...
dan seterusnya. Itu berdering "kasus khusus yang jahat" kepada saya.
Saya akan membahas beberapa kasus ini dengan kutipan dari buku ini, mencoba membatasi diri pada hal-hal yang hakiki, karena alasan hak cipta. Saya pikir kutipan ini termasuk dalam doktrin "penggunaan yang adil" dan mereka bahkan dapat merangsang untuk membeli buku - jadi saya harap tidak ada yang mengeluh (kalau tidak saya perlu menghapus sebagian besar, jika tidak semua). Selain itu, saya akan menahan diri untuk tidak melaporkan cuplikan kode karena alasan yang sama. Maaf soal itu. Beli buku untuk membaca tentang penalaran datail.
Nomor halaman antara tanda kurung dalam apa yang mengikuti.
NOT NULL Constraint (11)
Batasan kolom yang paling penting adalah NOT NULL, yang melarang penggunaan NULLs dalam kolom. Gunakan batasan ini secara rutin, dan hapus hanya ketika Anda memiliki alasan yang bagus. Ini akan membantu Anda menghindari komplikasi dari nilai NULL ketika Anda membuat pertanyaan terhadap data.
Itu bukan nilai ; itu adalah penanda yang memegang tempat di mana nilai mungkin pergi.
Lagi-lagi ini "nilai tetapi tidak cukup nilai" omong kosong. Sisanya tampaknya cukup masuk akal bagi saya.
(12)
Singkatnya, NULLs menyebabkan banyak fitur tidak beraturan dalam SQL, yang akan kita bahas nanti. Taruhan terbaik Anda adalah hanya menghafal situasi dan aturan untuk NULL ketika Anda tidak bisa menghindarinya.
Sepenuhnya dari SQL, NULLs dan infinite:
(104) BAB 3: DATA NUMERIK DALAM SQL
SQL belum menerima model IEEE untuk matematika karena beberapa alasan.
...
Jika aturan IEEE untuk matematika diizinkan dalam SQL, maka kita perlu mengetikkan aturan konversi untuk tak terbatas dan cara untuk mewakili nilai numerik persis tak terhingga setelah konversi. Orang-orang memiliki cukup masalah dengan NULLs, jadi jangan pergi ke sana.
Implementasi SQL ragu-ragu tentang apa arti sebenarnya NULL dalam konteks tertentu:
3.6.2 Fungsi Eksponensial (116)
Masalahnya adalah logaritma tidak terdefinisi kapan (x <= 0). Beberapa implementasi SQL mengembalikan pesan kesalahan, beberapa mengembalikan NULL dan DB2 / 400; versi 3 rilis 1 kembali * NEGINF (kependekan dari "infinity negatif") sebagai hasilnya.
Joe Celko mengutip David McGoveran dan CJ Date:
6 NULLs: Data yang Hilang dalam SQL (185)
Dalam buku mereka A Guide to Sybase dan SQL Server , David McGoveran dan CJ Date mengatakan: “Ini adalah pendapat penulis ini daripada NULLs, setidaknya seperti yang didefinisikan dan diimplementasikan saat ini dalam SQL, jauh lebih banyak masalah daripada nilainya dan harus dihindari; mereka menampilkan perilaku yang sangat aneh dan tidak konsisten dan bisa menjadi sumber kesalahan dan kebingungan yang kaya. (Harap dicatat bahwa komentar dan kritik ini berlaku untuk sistem apa pun yang mendukung NULL gaya SQL, tidak hanya untuk SQL Server secara khusus.) ”
NULL sebagai kecanduan narkoba :
(186/187)
Di sisa buku ini, saya akan mendesak Anda untuk tidak menggunakannya , yang mungkin tampak kontradiktif, tetapi tidak. Pikirkan NULL sebagai obat; gunakan dengan benar dan itu bekerja untuk Anda, tetapi menyalahgunakannya dan itu dapat merusak segalanya. Kebijakan terbaik Anda adalah untuk menghindari NULL ketika Anda bisa dan menggunakannya dengan benar ketika Anda harus.
Keberatan unik saya di sini adalah untuk "menggunakannya dengan benar", yang berinteraksi buruk dengan perilaku implementasi tertentu.
6.5.1 NULLS dalam Predikat Subquery (191/192)
Orang-orang lupa bahwa subquery sering menyembunyikan perbandingan dengan NULL. Pertimbangkan dua tabel ini:
...
Hasilnya akan kosong. Ini berlawanan dengan intuisi , tetapi benar.
(pemisah)
6.5.2 Solusi SQL Standar (193)
SQL-92 memecahkan beberapa masalah 3VL (logika tiga-nilai) dengan menambahkan predikat baru dari formulir:
<kondisi pencarian> IS [BUKAN] BENAR | SALAH | TIDAK DIKENAL
Tetapi UNKNOWN adalah sumber masalah itu sendiri, sehingga CJ Date, dalam bukunya yang dikutip di bawah ini, merekomendasikan dalam bab 4.5. Menghindari Nulls di SQL :
- Jangan gunakan kata kunci TIDAK DIKETAHUI dalam konteks apa pun.
Baca "ASIDE" di UNKNOWN, juga terhubung di bawah ini.
6.8 NULL dan Bahasa Inang (194)
Namun, Anda harus tahu bagaimana NULL ditangani ketika harus diteruskan ke program host. Tidak ada bahasa host standar yang mendefinisikan embedding mendukung NULLs, yang merupakan alasan bagus untuk menghindari menggunakannya dalam skema basis data Anda.
(pemisah)
6.9 Saran Desain untuk NULLs (195)
Merupakan ide bagus untuk mendeklarasikan semua tabel dasar Anda dengan batasan TIDAK NULL pada semua kolom bila memungkinkan. NULL membingungkan orang-orang yang tidak tahu SQL, dan NULL mahal.
Keberatan: NULLs membingungkan bahkan orang yang mengenal SQL dengan baik, lihat di bawah.
(195)
NULL harus dihindari dalam KUNCI ASING. SQL memungkinkan hubungan "manfaat keraguan" ini, tetapi dapat menyebabkan hilangnya informasi dalam kueri yang melibatkan gabungan. Misalnya, diberi kode nomor bagian dalam Inventaris yang direferensikan sebagai KUNCI LUAR NEGERI oleh tabel Pesanan, Anda akan mengalami masalah dalam mendapatkan daftar bagian yang memiliki NULL. Ini adalah hubungan wajib; Anda tidak dapat memesan bagian yang tidak ada.
(pemisah)
6.9.1 Menghindari NULL dari Program Host (197)
Anda dapat menghindari memasukkan NULL ke dalam database dari Program Host dengan beberapa disiplin pemrograman.
...
- Tentukan dampak dari data yang hilang pada pemrograman dan pelaporan:
Kolom angka dengan NULL adalah masalah, karena kueri yang menggunakan fungsi agregat dapat memberikan hasil yang menyesatkan.
(pemisah)
(227)
SUM () dari set kosong selalu NULL. Salah satu kesalahan pemrograman paling umum yang dibuat saat menggunakan trik ini adalah menulis kueri yang bisa mengembalikan lebih dari satu baris. Jika Anda tidak memikirkannya, Anda mungkin telah menulis contoh terakhir sebagai: ...
(pemisah)
10.1.1 Sumber NULLs (242)
Penting untuk mengingat di mana NULL dapat terjadi. Mereka lebih dari sekadar nilai yang mungkin dalam kolom . Fungsi agregat pada set kosong, GABUNGAN LUAR, ekspresi aritmatika dengan NULLs, dan operator OLAP semua mengembalikan NULLs. Konstruk ini sering ditampilkan sebagai kolom di LIHAT.
(pemisah)
(301)
Masalah lain dengan NULLs ditemukan ketika Anda mencoba untuk mengkonversi predikat IN ke predikat EXISTS.
(pemisah)
16.3 SEMUA Predikat dan Fungsi Ekstrem (313)
Ini berlawanan dengan intuisi pada awalnya bahwa kedua predikat ini tidak sama dalam SQL:
...
Tetapi Anda harus mengingat aturan untuk fungsi ekstrema — mereka menghapus semua NULL sebelum mengembalikan nilai yang lebih besar atau paling kecil. SEMUA predikat tidak menjatuhkan NULL, sehingga Anda bisa mendapatkannya di hasil.
(pemisah)
(315)
Namun, definisi dalam standar dituliskan dalam negatif, sehingga NULL mendapatkan manfaat dari keraguan. ...
Seperti yang Anda lihat, itu adalah ide yang baik untuk menghindari NULL dalam batasan UNIK.
Membahas GROUP BY:
NULL diperlakukan seolah-olah mereka semua sama satu sama lain , dan membentuk grup mereka sendiri. Setiap grup kemudian direduksi menjadi satu baris dalam tabel hasil baru yang menggantikan yang lama.
Ini berarti bahwa untuk GROUP BY klausa NULL = NULL tidak mengevaluasi ke NULL, seperti pada 3VL, tetapi mengevaluasi ke BENAR.
Standar SQL membingungkan:
ORDER BY dan NULLs (329)
Apakah nilai kunci pengurutan yang NULL dianggap lebih besar atau kurang dari nilai non-NULL ditentukan oleh implementasi, tetapi ...
... Ada produk SQL yang melakukannya dengan cara baik.
Pada bulan Maret 1999, Chris Farrar mengajukan pertanyaan dari salah satu pengembangnya yang menyebabkan dia memeriksa bagian dari Standar SQL yang saya pikir saya mengerti . Chris menemukan beberapa perbedaan antara pemahaman umum dan kata-kata sebenarnya dari spesifikasi .
Dan seterusnya. Saya pikir sudah cukup oleh Celko.
Tanggal CJ pada SQL NULLs
Tanggal CJ lebih radikal tentang NULLs: hindari NULLs di SQL, titik. Faktanya, bab 4 dari SQL dan Teori Relasionalnya: Cara Menulis Akurat Kode SQL berjudul "TANPA DUPLIKAT, TANPA NULL", dengan sub bab
"4.4 Apa yang Salah dengan Nulls?" dan "4.5 Menghindari Nulls dalam SQL" (ikuti tautan: terima kasih kepada Google Books, Anda dapat membaca beberapa halaman secara online).
Fabian Pascal pada SQL NULLs
Dari Masalah Praktis dalam Manajemen Basis Data - Referensi untuk Praktisi Berpikir (tidak ada kutipan online, maaf):
10.3 Implikasi Praktis
10.3.1 SQL NULLs
... SQL menderita dari masalah yang melekat pada 3VL serta dari banyak kebiasaan, komplikasi, berlawanan dengan intuisi, dan kesalahan langsung [10, 11]; di antara mereka adalah sebagai berikut:
- Fungsi agregat (misalnya, SUM (), AVG ()) mengabaikan NULLs (kecuali untuk COUNT ()).
- Ekspresi skalar pada tabel tanpa baris mengevaluasi dengan salah untuk NULL, bukan 0.
- Ekspresi "NULL = NULL" mengevaluasi ke NULL, tetapi sebenarnya tidak valid dalam SQL; namun ORDER BY memperlakukan NULLs sebagai sama (apa pun yang mereka mendahului atau mengikuti nilai-nilai "reguler" diserahkan kepada vendor DBMS).
- Ekspresi "x IS NOT NULL" tidak sama dengan "NOT (x IS NULL)", seperti halnya dalam 2VL.
...
Semua dialek SQL yang diimplementasikan secara komersial mengikuti pendekatan 3VL ini, dan, dengan demikian, mereka tidak hanya menyelesaikan masalah ini, tetapi mereka juga memiliki masalah implementasi spefic, yang bervariasi di seluruh produk .