SQL'de NULL Tuhaflığı
(jirevwe.github.io)-
SQL'de NULL değerleri kendine özgü bir şekilde ele alınır. UNIQUE kısıtlaması olan bir sütun birden fazla NULL değer içerebilir.
- Bunun nedeni, her NULL değerinin diğer NULL'lardan farklı bağımsız bir değer olarak kabul edilmesidir.
- SQLite, Postgres ve MySQL'in hepsi aynı şekilde davranır.
-
Temel durum
select '' = ''; -- Returns 1 (true) boş dizge eşittir select 1 = 1; -- Returns 1 (true) sayılar eşittir select 1 = 0; -- Returns 0 (false) sayılar farklıdır select null = null; -- Returns NULL (null) ha?- NULL, "bilinmeyen değer"i temsil eden bir yer tutucu olduğu için iki bilinmeyen değerin eşit olduğu kabul edilmez.
ISoperatörü kullanılarak NULL'un kimliği kontrol edilebilir. Örneğin,null is nullTRUE döndürür.
-
Benzersizlik hakkında
- UNIQUE kısıtlaması olan bir sütunda NULL değerler varsa, bu NULL değerler birbirinden farklı kabul edilir ve benzersizlik kısıtlamasını ihlal etmez.
- Örneğin,
('ray@mail.com', NULL)ve('ray@mail.com', NULL)birbirinden farklı satırlar olarak kabul edilir.
-
NULL neden böyle ele alınıyor
- SQLite ve diğer SQL uyumlu veritabanları, NULL'u diğer veritabanlarıyla tutarlı biçimde işlemek için bunu böyle uygular. SQL standart dokümanları NULL'un her yerde benzersiz olması gerektiğini önerir, ancak pratikte çoğu SQL motoru SELECT DISTINCT veya UNION içinde NULL'u benzersiz olarak ele almaz.
-
Benzersizlik nasıl garanti edilir
-
Üretilmiş sütun kullanımı
- Her zaman NULL olmayan deterministik bir değer taşıyan bir sütun oluşturarak bu sorun hafifletilebilir. Örneğin, NULL değerleri ikame etmek için
COALESCE(deleted_at, '1970-01-01')kullanılabilir. - Bu yöntem tabloya ek alan eklediği için yer kaplayabilir.
- Her zaman NULL olmayan deterministik bir değer taşıyan bir sütun oluşturarak bu sorun hafifletilebilir. Örneğin, NULL değerleri ikame etmek için
-
Kısmi indeks kullanımı
deleted_atNULL olduğunda yalnızcaemailiçin kısmi bir indeks oluşturarak benzersizlik garanti edilebilir.- Kısmi indeksler tabloyu genişletmeden daha az yer kaplar ve aynı kayıt çiftini tekrar tekrar silerken hata oluşmaz.
-
-
Güncelleme
- Oracle boş dizgeyi NULL olarak ele alır.
-
Sonuç
- ORM kullanırken görünmez olsa da, SQL NULL'un kendine özgü işlenişi kafa karışıklığına yol açabilir. SQL standart dokümanları kamuya açık değildir ve yalnızca ücret ödenerek edinilebilir.
2 yorum
Tüm null'lar tuhaftır.
Bu yüzden normal SQL
null'ı bile sanki daha tuhafmış gibi görünüyor…Tek gözlüler ülkesinde iki gözlü anormal sayılır…
Hacker News görüşü
SQL'deki NULL, Kleene'in TRUE-FALSE-UNKNOWN mantığına dayanır. NULL'ı UNKNOWN olarak okursanız birçok işlemi daha sezgisel anlamak mümkün olur
NULLS NOT DISTINCTkullanılarak benzersiz indeks oluşturulabilir1970'lerde NULL kavramı ortaya atıldığında, gelecekte büyük kafa karışıklığına yol açacağı düşünülüyordu. 45 yıl sonra bugün hâlâ tartışılıyor
NULL'ı sezgisel olarak anlama biçimi: Belirli bir tablo hücresindeki NULL değeri, 'değer yok' anlamını ifade etmenin bir yoludur. Benzersiz değerler istendiğinde, değerin olmadığı durumlar hesaba katılmamalıdır
ORM kullanımına yönelik şüphecilik: ORM kullanışlıdır ama ilişkisel veritabanlarının gerçekte nasıl çalıştığını öğrenmeyen bir nesil ortaya çıkardı. SQL NULL'ının davranışı temel ilişkisel cebirle uyumludur; sorun C tarzı NULL'dır
Blackadder bölümündeki bir diyaloğun NULL karşılaştırmasının mizahını hatırlattığı söyleniyor
Oracle'da NULL'ın boş string ile aynı sayılması garip bulunuyor
Nesne yönelimli bağlamda "null", belirli bir özelliğin bir değeri olmadığını göstermek için kullanışlıdır. JavaScript'te null ve undefined vardır; undefined'ın değerin bilinmediği, null'ın ise değerin olmadığı anlamına geldiği varsayılabilir
NULL, tekrar olmadığı anlamında garip değildir. NULL'lar birbirine eşit olmadığı için tekrar sayılmaz. NULL anlambilimini beğenmiyorsanız sentinel değer kullanabilirsiniz
SQL NULL, var olmayan değerlere sahip kayıtlar söz konusu olduğunda ilişkisel mantığın nasıl çalışmasını istediğinizi düşününce garip değildir