İş anahtarlarının (sadece ID değil, aynı zamanda "doğal" alanlar üzerinden) benzersizliğini kontrol etmek, kurumsal uygulamalar için uzun zamandır gündemde. Bu tür anahtarlar genellikle karmaşık (birden fazla sütun) olabilir ve NULL değerlerine izin verebilir. SQL'in standart araçları - UNIQUE CONSTRAINT veya benzersiz indeksler - sınırlamalara sahiptir: SQL standartlarına göre, UNIQUE anahtarının bileşenlerinden en az birinin NULL olduğu birden fazla satır benzersiz kabul edilir ve kısıtlamayı ihlal etmez.
İş mantığı, NULL değerleri de içeren sütunlar kümesinin eşit şekilde benzersiz olmasını talep edebilir ve SQL standartlarının davranışı (NULL ≠ NULL) bu senaryoyu bozar. Örneğin, (pasaport_numarası, pasaport_serisi) çiftine sahip bir tablomuz var ve bunlardan en az biri NULL olabilir. Ancak değerler eşleşirse, yinelenenleri engellememiz gerekmektedir.
En popüler DBMS'lerde, benzersizlik kontrolünü tetikleyiciler aracılığıyla gerçekleştirmek veya koşullu kısmi indeksler kullanmak ya da NULL değerlerini eşit kabul eden fonksiyonlar (örneğin ISNULL veya COALESCE) kullanmak çözüm olarak önerilmektedir. PostgreSQL'de ifade üzerinden benzersiz bir indeks kullanarak bir örnek:
CREATE UNIQUE INDEX idx_passport_unique ON persons ( COALESCE(passport_number, ''), COALESCE(passport_series, '') );
Uygulama mantığı seviyesinde çoğu zaman ek kontrol yapmak gerekir, böylece ekleme aşamasında yinelenenleri kaçırmamış oluruz.
Anahtar özellikler:
NULL içeren sütunlar varsa, benzersiz indeksin dublikat eklemeyi engelleyeceğinden emin olabilir miyiz?
Hayır, olamazsınız. SQL'de NULL ile davranış özeldir: en az birinin NULL olduğu benzer değer setlerine sahip satırları indeks farklı olarak kabul eder ve aynı anda saklamalarına izin verir.
Farklı DBMS'leri NULL benzersizliğini farklı şekilde uygulayabilir mi?
Evet, aralarında farklılıklar vardır. Örneğin, Oracle'da benzersiz indeks birden fazla NULL kabul ederken, MS SQL'de bir tane kabul eder. PostgreSQL, ifadeler ile kısmi indeks oluşturabilir.
Sorunu yalnızca DDL seviyesinde ve tetikleyiciler olmadan aşmak mümkün mü?
Bazı DBMS'lerde evet, örneğin COALESCE ile. Ancak her zaman değil ve karmaşık bir davranış (NULL'ın bir dublikat olarak kabul edilmesi gerektiği) gerektiğinde mantıksal kontroller veya tetikleyiciler kullanmak gerekecektir.
Kritik olmayan bir veritabanında (email, departman kodu) için benzersiz bir indeks kullanma kararı alındı; her iki alan da NULL değerine izin veriyor. Sonuç olarak, birçok kez dublikatlar ortaya çıktı ve bu da dış entegrasyonları bozdu.
Artılar:
Eksiler:
PostgreSQL'de iş anahtarı (pasaport numarası, seri numarası) COALESCE üzerinden indeks ile oluşturuldu ve ayrıca uygulama tarafında kontrol eklendi.
Artılar:
Eksiler: