14 Aralık 2010 Salı

Primary Key - Unique Indeks / Not Null Constraint

Merhaba,

Fiziksel tablo objeleri üzerinde bildiğiniz üzere primary key, yani birincil anahtar yaratabiliyoruz. Birincil anahtar yaratmamızın temel nedeni aslında tabloya olan veri girişini kontrol etmek ve kontrolünüz dışında veri girişini engellemek. Bir diğer sebep ise tablo içindeki verilerin unique, yani benzersiz, tekil olmasını istiyor olmanız. Bir başka neden ise tanımladığınız sütunların NULL içermemesini istiyor olmanız. Sonradan yaptığım bu ekte ise şunu belirtmem gerekiyor; bir tablo üzerinde bir tane primary key yaratılabilir. Bir tabloda iki tane primary key olamaz.


Her ne sebep olursa olsun gündelik hayatımızda tablolar üzerinde çok sayıda birincil anahtar ve hatta bu birincil anahtarlara referans olan (foreign key) anahtarlar yaratırız. Bunların hepsinin altında yatan neden objeler arasındaki ilişkinin tutarlılığını ve sağlamlığını tesis etmek istememiz.

Bu yazımda çok fazla detaya girmeden birincil anahtar ve diğer constraintler arasındaki bağlantıları ve özellikleri belirteceğim. Öncelikle bir birincil anahtar nedir? Birincili anahtarın tam tanımını şöyle yapabiliriz; her bir sütun üzerinde teker teker not null constraint yaratmak ve bu yarattığı constraint'in üzerine bütün sütunlar için bir unique constraint eklemek ve son olaraksa bir unique indeks yaratmak. Bunların hepsini birleştirdiğiniz zaman iki tane obje elde edersiniz. Bir tanesi birincil anahtar constraint'i, diğeri de unique bir index. Bu noktada mutlaka aklınızda tutmanızı istediğim bir bilgi var. Birincil anahtar constraint'ini yaratmadan önce eğer bir unique veya non-unique indeks yaratırsanız ve ardından, bu indekse dahil olan sütun veya sütunlar üzerinde composite veya composite olmayan bir birincil anahtar tanımlarsanız, bu birincil anahtar daha önce yarattığınız indeksi kendi bünyesinde kabul edecek ve bir tane daha unique indeks yaratmanız gerekmeyecek. Önemli; birincil anahtar sütun veya sütunların benzersiz ve not null olacağını garanti ettiği için indeksin benzersiz veya benzersiz olmayan indeks olup olmaması önemli değildir. Eğer tanımlayacağınız indeks bir partitioned indeks ise önce indeksi, ardından birincil anahtar constraint'ini yaratmanızda fayda var. Aksi halde indekse sonradan partition eklemeniz gerekecektir.

Peki primary key ve unique constraint arasında ne fark var? Neden unique constraint değil de primary key constraint? 2 tane sebebi var. Birincisi unique constraint'in içerisine null değer girilebiliyorken birincil anahtara ait bir sütuna null giremezsiniz. İkinci sebep ise birincil anahtara ve benzersiz kısıtlamaya referans anahtarlar yaratabilirsiniz. Bu yarattığınız referans anahtarları içerisine null da girebiliriz. İşte bu sebeplerden dolayı bir seçim yapabilirsiniz. Buna ek olarak benzersiz constraint yaratılırken, benzersiz indeks yaratılmaz, bu sadece birincil anahtar içindir. Not null constraint'i ise oldukça farklıdır. Bir tabloya sonradan primary key veya unique constraint ekleyebilirsiniz. Bütün constraint'ler zaten ya tabloyu yaratırken ya da tabloyu yarattıktan sonra oluşturulabilir ancak not null'un farklı olmasının nedeni, not null constraint'ini yeni bir sütun eklerken yaratamayız, eğer tabloda bir veya birden çok veri varsa. Bunu yapabilmek için tablonun tamamen boş olması veya her satırın ve her sütunun null olması gerekiyor. Aksi takdirde not null constraint'ini yaratamayız.

Bir ek, all_constraints data dictionary görüntüsünde birincil anahtar, P (Primary) olarak, benzersiz constraint U (Unique) olarak, NOT NULL constraint C (Check) olarak gösterilmektedir. Foreign key ise R (Referencial) olarak gösterilmektedir. Bu da ayrıca bir sertifikasyon sorusu olarak karşınıza çıkabilir.

Bir tablo üzerinde istediğimiz zaman (eğer tablo üzerinde bir kilit yoksa) constraint'leri deaktif konuma getirebiliriz. Bunu yapmak için 4 koşul bulunmaktadır;

1) ENABLE VALIDATE;
2) ENABLE NOVALIDATE;
3) DISABLE VALIDATE;
4) DISABLE NOVALIDATE;

ENABLE ile ENABLE VALIDATE komutları aynı işi görmektedir ve VALIDATE veya NOVALIDATE yazılmadığı takdirde ENABLE VALIDATE komutu varsayılandır. Constraint yeniden yaratılırken bir defa daha kontrol edilir ve şartları sağlayıp sağlamadığı incelenir. ENABLE NOVALIDATE ise yine constraint'i aktive eder ve şartlarını kontrol eder ama bunu yaparken önceden girilmiş olan veri kontrol edilmez. DISABLE'da da aynı işlerin tersi gerçekleştirilmektedir.

İyi çalışmalar.

Ogan

4 yorum:

Gökhan Atıl dedi ki...

Ogan,

Yazılarını ilgi ile takip ediyorum. Primary key kısıdı ile unique kısıdı arasındaki farkları söylerken "birincil anahtara referans anahtarlar yaratabilirsiniz" demişsin. Bu cümleden sanki unique alanlara referans anahtar yaratılamıyormuş gibi anlaşılıyor ama unique alanlara da referans anahtarlar yaratılabilir.

Ayrıca küçük bir ek bilgi: Tablodaki her hangi bir kısıt "DISABLE VALIDATE" yapılırsa tablo read-only hale gelir.

Kolay gelsin

Gökhan

Ogan Ozdogan dedi ki...

Selam,

Yorum ve ilgin için çok teşekkür ederim. Evet, referans anahtarları hem birincil anahtar hem de benzersiz kısıt için tanımlayabiliyoruz.

İyi akşamlar.

Ogan

Savaş Külah dedi ki...

Merhaba Ogan,

Primary ve foreign keylerle alakalı olarak özellikle yazılım geliştiricilerin dikkat etmesi gereken bir durum var:

http://savaskulah.wordpress.com/2008/02/10/unindexed-foreign-key-cause-full-table-lock-on-child-table/

Ayrıca yine yazılım geliştiriciler için kullanılabilir bir özellik olarak Deferrable Constraint özelliğinden de bahsedilebilir.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_10003.htm

Saygılar,

Ogan Ozdogan dedi ki...

Merhaba,

Indekslenmeye FK'ların deadlock oluşturduğu birçok yerde ve forumda tartışıldı ve bence de oldukça önemli bir konu.

Paylaştığın link'ler için çok teşekkür ederim. Bir ek yapmam gerekirse;

1.Session;

SQL> create index idx_child on child(x);

Index created.

SQL> insert into child values ( 2 );

1 row created.

2.Session;

SQL> update parent set x=1 where x=1;

1 row updated.

Özellikle Oracle forumlarında günde en az 1 tane konu açılmazsa olmaz dediğim konulardan birisi bu indekslenmeyen FK'nin yarattığı deadlock. Gerçi konuyu açan kişi aslında deadlock'ın ne olduğundan bihaber olabiliyor ki FK'nın indekslenmediğini hiç tahmin edemeyebiliyorlar.

İyi çalışmalar.

Ogan

Takip et: @oganozdogan