Veri tabanı yönetim sistemlerinin sağlamış olduğu konulardan biri de veriler arasındaki tutarlılığı kendi içerisinde sağlayarak istemci tarafında herhangi bir işleme gerek bırakmamasıdır. Bu yazımızda veri bütünlüğünü kolon seviyesinde ve tablo seviyesinde inceleyeceğiz.
Kolon Seviyesinde Veri Bütünlüğü
Kolon seviyesinde tanımlanan şartlar (constraint) aynı tablo içerisinde kolonda yer alan değerlerin tutarlılığını sorgular.
Kolon seviyesinde veri bütünlüğü sağlama yollarını inceleyelim;
Primary Key:
Normalizayon kuralları gereği her tabloda en az bir birincil anahtar alan bulunmak zorundadır. Tanımlanan bu anahtar alan primary key olarak tanımlanır ve NULL
değer kabul etmeyen tekil bir anahtardır. Tablo üzerinde clustred bir anahtar tanımlı değilse ve primary key tanımında NONCLUSTERED değeri kullanılmadıysa clustered yapıda oluştururlur. Her tabloda en fazla bir tane olabilir.
CLUSTERED INDEX: Clustered index olarak tanımlanan index disk üzerinde fiziksel olarak sıralı tutulur. Sıralı okuma yapılacak alanlarda veriler ard arda olduğundan okuma hızlı olur. Her tabloda en fazla bir tane olabilmesinin nedeni de verilerin fiziki olarak sıralanıyor olmasıdır.
NONCLUSTERED INDEX: Bu index türünde de veriler clustered index’e göre işaret edilir. Aşağıdaki tablolarda bu iki kavramı örnekle açıklamaya çalışalım.
İlk tablomuzda Id alanı üzerinde Clustered Primary key var ve görüldüğü gibi Id alanına göre sıralıdır.
Id (PK) | Name | Surname | Birthday |
1 | Sait | ORHAN | 09.11.1989 |
2 | Yavuz | Varol | 24.12.1954 |
3 | Cemal | Duran | 15.08.1974 |
4 | Ahmet | Karadavut | 08.07.1987 |
Şimdi de Name alanı üzerinde Nonclustered Index oluşturalım.
Name | Id |
Ahmet | 4 |
Cemal | 3 |
Sait | 1 |
Yavuz | 2 |
Nonclustered index, tabloda göründüğü gibi üzerinde index oluşturulacak kolon/kolonlar ve yerini gösteren clustered index alanını içeren bir tablo şeklinde tutulur.
Primary key tanımlama için kullanılan genel ifade:
CREATE TABLE tablo_ismi(
sutun_adı sutun_veri_turu CONSTRAINT primary_key_adı PRIMARY KEY [CLUSTERED|NONCLUSTERED],
-- Diğer sütun tanımları
)
Var olan tablo üzerinde PRIMARY KEY tanımlama:
ALTER TABLE tablo_ismi ADD CONSTRAINT primary_key_adı PRIMARY KEY (sutun_ismi) [CLUSTERED|NONCLUSTERED]
UNIQUE Constraint:
Primary Key tanımında sadece bir tane olabileceğini belirtmiştirk. Unique şartında ise birden fazla olabilr. Unique index tanımlandığı kolonda her değerden en fazla bir tane bulunabilir. NULL değer taşıyan bir satır olması durumunda ikinci bir NULL geldiğinde kabul etmeyecektir. Eğer var ise tekil yok ise NULL değer taşıyabilir diye bir şart olması durumunda bunu şartlı index oluşturarak yapabilirsiniz.
Tablo Oluşturma Sırasında UNIQUE INDEX Oluşturma:
CREATE TABLE table_ismi(
--SÜTUN TANIMLAMALARI
CONSTRAINT unique_index_ad UNIQUE [CLUSTERED|NONCLUSTERED] )
Tanımlı Tablo Üzerinde UNIQUE Tanımlama:
ALTER TABLE table_ismi ADD CONTRAINT unique_index_ad UNIQUE [CLUSTERED|NONCLUSTERED]
Şartlı index tanımlama için de aşağıdaki şekilde bir tanımlama yapılabilir;
CREATE UNIQUE INDEX filtered_unique_index
ON table_name([Name])
WHERE [Name] IS NOT NULL
Oluşturduğumuz bu şartlı indexte [Name] alanı NULL olmaması durumunda çalışır.
Tablo Seviyesinde Veri Bütünlüğü
Tablo boyutunda veri bütünlüğünü temelde iki şekilde sağlayabiliriz.
Kolonlar Arası Constraint ile:
Bu versiyonda veri girişinde bir birine bağımlı olan kolonlar arasında CHECK constraint ayarlanarak veri bütünlüğü sağlanabilir. Örneğin: Kişiler tablosunda kayıt tarihi alanının doğum tarihi kolonundan büyük olma şartı gibi.
CREATE TABLE Kisiler( Id INT PRIMARY KEY IDENTITY, Ad NVARCHAR(50) NOT NULL, DogumTarih DATETIME, KayitTarih DATETIME, CONSTRAINT Kayit_Tarih_Kontrol CHECK (KayitTarih > DogumTarih) )
Foreign Key Ayarlama:
Tablonun belli bir alanına girilen değerin başka bir tablonun tekil alanında olma şartı durumunda foreign key kullanılır. Örneğin: Kişiler tablosunda “Unvan_Kodu” alanı olsun. Bu alana girilen değerin Unvanlar tablosunda olması gerekmektedir. Aksi durumda kişinin unvanını gösteren koda karşılık bir unvan olmadığından tutarsızlık meydana gelecektir.
Foreign key olarak tanımlanan alan NULL değer taşıyabilir. Mesela kişiyi veri tabanına ilk kayıtta unvanı tanımlanmamış olabilir, bu durumda unvan tanımlanana kadar alan NULL değer olarak atanacaktır.
CREATE TABLE tablo_ismi(
-- sutun tanımları
CONSTRAINT foreign_key_adi FOREIGN KEY(foreign_key_tanımlanılacak_kolon_adı) REFERENCES ikinci_tablo_adı(ikinci_tablo_tekil_kolon_adı))
Foreign key tanımında referans alınan kolonda değişiklik veya silme olması durumunda referans alan kolonda hangi işlemin olması gerektiğini de belirtmemiz gerekmektedir aksi durumda bir veri tutarsızlığı durumu ortaya çıkar. Mesela daha önce “Müdür” unvanının kodu 1, “Şef” unvanının kodunun 2 olduğunu varsayalım. Herhangi bir sebepten dolayı “Müdür” unvanının kodu 2 olarak değiştirilmesi gerekirse ve bu değişiklik Kisiler tablosuna da işlenmezse daha önce şef pozisyonunda olan her bir kişi veri tabanında artık müdür olarak görünecek. Bunun önüne geçmek için SQL Server foreign key alanı üzerinde ON DELETE ve ON UPDATE işleminde hangi işlemin olacağını belirtebiliriz.
İfadenin genel tanımı aşağıdaki gibidir:
ON {DELETE | UPDATE} {CASCADE | NO ACTION | SET DEFAULT | SET NULL}
- ON DELETE: Referans alınan değer silindiğinde
- ON UPDATE: Referans alınan değer güncellendiğinde yapılacak işlemi ifade eder.
Bu ifadelerden sonra girilecek değerler:
- CASCADE: Referans alınan değer üzerinde yapılan değişiklik referans alan değerler üzerinde de işlenir. Referans alınan değerin silinmesi durumunda referans alan kayıtlar da silinir.
- SET DEFAULT: Referans alınan değerin silindiğinde, referans alan kayıtta bir default tanım var ise değer default olarak değiştirilir.
- SET NULL: Referans alınan değerin silindiğinde, referans alan kayıt NULL değer kabul ediyor ise değer NULL olarak değiştirilir.
- NO ACTION: Referans alınan değer silindiğinde, referans alan bir kayıt var ise silinmesine müsaade edilmez, varsayılan olarak atanan işlem budur.
Veri tabanında ayarlanmış veri bütünlüğü kuralları hem veri girişinde oluşacak hataları engeller hem de istemci uygulamayı geliştirirken sorgulanması gereken bir dizi kural için kodlama yapma gerekliliğini ortadan kaldırır.