Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt Kısıtlama Kuralları Nasıl Yapılır?

Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt Kısıtlama Kuralları Nasıl Yapılır?
Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt Kısıtlama Kuralları Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Uygulamalı örnekleri takip edebilmeniz için sisteminizde PostgreSQL, MySQL 8.0+ veya SQL Server gibi modern bir ilişkisel veritabanı yönetim sistemi (RDBMS) kurulu olmalıdır. Ayrıca, SQL sorgularını çalıştırabileceğiniz bir arayüz (DBeaver, pgAdmin veya komut satırı) kullanmanız önerilir.

  • Modern bir ilişkisel veritabanı sunucusu (PostgreSQL 16+ önerilir).
  • SQL sözdizimine temel düzeyde hakimiyet.
  • Veri modelleme mantığına dair temel bilgi.

Temel Kısıtlama Türleri: NOT NULL ve UNIQUE

Veri bütünlüğünün ilk adımı, sütunların boş geçilemez (NOT NULL) olmasını sağlamak ve benzersiz (UNIQUE) değerler gerektiren alanları korumaktır. Bu kısıtlamalar, veritabanı şeması oluşturulurken doğrudan tablo tanımına eklenmelidir.

Aşağıdaki örnekte, bir kullanıcı tablosu oluştururken e-posta adresinin benzersiz olması ve ad soyad bilgisinin zorunlu tutulması sağlanmıştır:

CREATE TABLE kullanicilar (
    id SERIAL PRIMARY KEY,
    ad_soyad VARCHAR(100) NOT NULL,
    eposta VARCHAR(255) UNIQUE NOT NULL,
    kayit_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Bu kod, veritabanı seviyesinde e-posta adresinin mükerrer kaydedilmesini engeller. Eğer aynı e-posta ile ikinci bir kayıt denerseniz, veritabanı motoru "Unique constraint violation" hatası dönecektir.

CHECK Kısıtlaması ile Mantıksal Kurallar

CHECK kısıtlamaları, bir sütundaki verinin belirli bir mantıksal koşulu karşılayıp karşılamadığını denetler. Örneğin, bir ürünün fiyatının negatif olamayacağını veya bir yaş sınırının belirli bir aralıkta olması gerektiğini bu yöntemle zorunlu kılabilirsiniz.

Aşağıdaki örnekte, ürün fiyatının sıfırdan büyük olması kuralını uygulamaktayız:

ALTER TABLE urunler 
ADD CONSTRAINT chk_fiyat_pozitif 
CHECK (fiyat > 0);

Bu kural, uygulama katmanında bir hata oluşsa bile veritabanına asla hatalı fiyat girişinin yapılmamasını garanti eder. Test etmek için INSERT INTO urunler (fiyat) VALUES (-50); sorgusunu çalıştırarak kısıtlamanın tetiklendiğini görebilirsiniz.

Yabancı Anahtarlar (Foreign Keys) ile İlişkisel Bütünlük

İlişkisel veritabanlarında, tablolar arasındaki bağı korumak için FOREIGN KEY kullanılır. Bu kısıtlama, bir tabloda referans verilen verinin diğer tabloda var olmasını zorunlu kılar. Bu, "yetim kayıt" oluşumunu engeller.

CREATE TABLE siparisler (
    id SERIAL PRIMARY KEY,
    kullanici_id INT NOT NULL,
    tutar DECIMAL(10, 2),
    CONSTRAINT fk_kullanici 
    FOREIGN KEY (kullanici_id) 
    REFERENCES kullanicilar(id) 
    ON DELETE CASCADE
);

Burada ON DELETE CASCADE kullanımı, bir kullanıcı silindiğinde ona bağlı tüm siparişlerin de otomatik olarak temizlenmesini sağlar. Bu, veritabanı tutarlılığını korumak için kritik bir adımdır.

Veri Kısıtlama Yöntemlerinin Karşılaştırılması

Kısıtlama Türü Amacı Avantajı
NOT NULL Veri boşluğunu engeller Hatalı veri girişini ilk aşamada durdurur.
UNIQUE Mükerrer kaydı önler Veri tekilliğini garanti eder.
CHECK Mantıksal doğrulama İş kurallarını veritabanına gömer.
FOREIGN KEY İlişki bütünlüğü Referans hatasını engeller.

Trigger (Tetikleyici) ile Gelişmiş Kısıtlamalar

Standart kısıtlamaların yetersiz kaldığı durumlarda, SQL Trigger yapıları devreye girer. Triggerlar, belirli bir işlem (INSERT, UPDATE, DELETE) gerçekleşmeden önce veya sonra çalışan özel fonksiyonlardır.

CREATE OR REPLACE FUNCTION kontrol_mesai_saati() 
RETURNS TRIGGER AS $$
BEGIN
    IF (EXTRACT(HOUR FROM NEW.kayit_tarihi) < 9 OR EXTRACT(HOUR FROM NEW.kayit_tarihi) > 18) THEN
        RAISE EXCEPTION 'Kayıt sadece mesai saatleri içerisinde yapılabilir.';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_mesai_kontrol
BEFORE INSERT ON islemler
FOR EACH ROW EXECUTE FUNCTION kontrol_mesai_saati();

Bu örnekte, veritabanı seviyesinde mesai saatleri dışında kayıt girişini engelleyen dinamik bir kural tanımladık. Bu tür kısıtlamalar, karmaşık iş akışları için vazgeçilmezdir.

Güvenlik ve Performans İpuçları

Kritik Uyarı: Veritabanı kısıtlamaları, uygulamanızın güvenlik katmanının bir parçasıdır ancak tek başına yeterli değildir. SQL Injection saldırılarına karşı her zaman parametreli sorgular (Prepared Statements) kullanın. Ayrıca, veritabanı kısıtlamalarını aşırı karmaşık hale getirmek sorgu performansını düşürebilir; bu nedenle dizinleme (indexing) stratejilerini göz ardı etmeyin.

Uygulama kodunuzda (örneğin PHP veya Python ile) veritabanı hatalarını yakalamak için try-catch blokları kullanmanız, kullanıcıya anlamlı hata mesajları dönmenizi sağlar.

-- Performans için dizinleme örneği
CREATE INDEX idx_kullanici_eposta ON kullanicilar(eposta);

Sıkça Sorulan Sorular

CHECK kısıtlaması ile uygulama katmanı doğrulaması arasındaki fark nedir?

Uygulama doğrulaması kullanıcı deneyimi için gereklidir, ancak veritabanı kısıtlaması "son savunma hattı"dır. Doğrudan veritabanına erişen diğer uygulamalar veya manuel sorgular için veritabanı kısıtlaması tek güvenli yoldur.

Bir kısıtlamayı nasıl güncellerim?

SQL'de kısıtlamayı doğrudan güncellemek yerine, önce ALTER TABLE tablo_adi DROP CONSTRAINT kısıtlama_adi; komutuyla silip, ardından yeni kuralla tekrar eklemeniz gerekir.

Performans üzerinde olumsuz etkisi olur mu?

Çok sayıda karmaşık CHECK veya TRIGGER kısıtlaması, her yazma işleminde ekstra işlem yükü getirir. Ancak, veri bütünlüğü sağlanan bir veritabanında sorgu optimizasyonu daha kolaydır.

NULL değerler UNIQUE kısıtlamasını nasıl etkiler?

Çoğu SQL veritabanında, UNIQUE kısıtlaması NULL değerleri birbirinden farklı kabul eder. Yani birden fazla NULL değerine izin verilebilir. Bu davranışı değiştirmek için özel bir kısıtlama (Partial Index) gerekebilir.

Hangi kısıtlama türü daha güvenlidir?

Tüm kısıtlama türleri veritabanı motoru tarafından zorunlu kılındığı için aynı güvenlik seviyesine sahiptir. Ancak, referans bütünlüğü için FOREIGN KEY kullanımı en kritik olanıdır.

Veri Kısıtlama Kurallarında Hata Ayıklama ve Yönetim Stratejileri

Veritabanı kısıtlamaları, veri bütünlüğünü korumak için mükemmel araçlar olsa da, bazen karmaşık hata mesajlarına neden olabilirler. Özellikle canlı sistemlerde, "Constraint Violation" (Kısıtlama İhlali) hataları ile karşılaşıldığında, sorunun kaynağını hızlıca tespit etmek kritik bir beceridir. Hata ayıklama sürecinde izlemeniz gereken adımlar şunlardır:

  • Hata Mesajlarını Analiz Edin: Çoğu veritabanı motoru, ihlal edilen kısıtlamanın adını hata mesajında döndürür. Kısıtlamalarınıza anlamlı isimler (örneğin: fk_orders_customer_id yerine fk_orders_customer_id_ref) vermek, hata loglarını okumayı kolaylaştırır.
  • İhlal Eden Veriyi Sorgulayın: Bir CHECK veya FOREIGN KEY kısıtlaması hata verdiğinde, hangi satırın bu kuralı bozduğunu bulmak için SELECT sorgularınızı kısıtlama mantığına göre filtreleyin.
  • İşlem (Transaction) Yönetimi: Toplu veri girişlerinde, bir kısıtlama hatası tüm işlemin geri alınmasına (rollback) neden olur. Hata ayıklarken SAVEPOINT kullanarak veritabanı üzerinde kısmi geri almalar yapabilirsiniz.

Aşağıdaki örnek, bir CHECK kısıtlaması ihlal edildiğinde hatanın nasıl yakalanıp yönetilebileceğine dair bir senaryoyu göstermektedir:

-- Hata ayıklama için kısıtlamayı tetikleyen senaryo
BEGIN TRY
    INSERT INTO Urunler (UrunAdi, Fiyat) VALUES ('Test Ürün', -50);
END TRY
BEGIN CATCH
    PRINT 'Hata Kodu: ' + CAST(ERROR_NUMBER() AS VARCHAR);
    PRINT 'Hata Mesajı: ' + ERROR_MESSAGE();
    -- Burada hata log tablosuna kayıt atılabilir
END CATCH;

Üretim Ortamında Kısıtlama Değişiklikleri ve Deployment

Canlı bir veritabanında kısıtlama eklemek veya değiştirmek, veri hacmi büyüdükçe riskli bir operasyona dönüşebilir. Özellikle milyonlarca satırın bulunduğu tablolarda ALTER TABLE komutları, veritabanını kilitleyebilir (lock) ve uygulamanın yanıt vermemesine neden olabilir.

Profesyonel bir deployment sürecinde şu stratejiler uygulanmalıdır:

  1. Önce Veriyi Temizleyin: Yeni bir NOT NULL veya CHECK kısıtlaması eklemeden önce, mevcut verilerinizin bu kurala uyduğundan emin olun. Aksi takdirde ALTER komutu başarısız olacaktır.
  2. Kısıtlamayı "NOCHECK" ile Ekleyin: SQL Server gibi sistemlerde, mevcut verileri kontrol etmeden kısıtlamayı ekleyip daha sonra WITH CHECK komutuyla doğrulama yapabilirsiniz. Bu, kilitlenme süresini azaltır.
  3. İndeksleri Kontrol Edin: UNIQUE kısıtlamaları arka planda indeks oluşturur. Büyük tablolarda bu işlem ciddi kaynak tüketir; bu nedenle yoğun olmayan saatlerde (off-peak hours) uygulanmalıdır.

Aşağıdaki örnek, mevcut verileri bozmadan kısıtlama ekleme yöntemini göstermektedir:

-- Mevcut veriyi kontrol etmeden kısıtlamayı ekle
ALTER TABLE Siparisler WITH NOCHECK 
ADD CONSTRAINT chk_SiparisTarihi 
CHECK (SiparisTarihi >= '2023-01-01');

-- Daha sonra veriyi doğrula
ALTER TABLE Siparisler WITH CHECK 
CHECK CONSTRAINT chk_SiparisTarihi;
Profesyonel İpucu: Deployment süreçlerinizde "Migration" (Göç) araçlarını kullanın. Bu araçlar, kısıtlama değişikliklerini versiyon kontrollü bir şekilde yönetmenizi ve olası hatalarda geri dönüş (rollback) yapmanızı sağlar.

Sonuç

SQL & Veritabanı ile veri kayıt kısıtlama kurallarını uygulamak, yazılımınızın ömrünü uzatan ve veri hatalarını minimize eden profesyonel bir yaklaşımdır. Bu rehberde öğrendiğiniz NOT NULL, UNIQUE, CHECK ve FOREIGN KEY yapıları, veritabanı mimarinizin temel taşlarını oluşturur. Bir sonraki adım olarak, veritabanı rollerini ve yetkilendirme (GRANT/REVOKE) süreçlerini inceleyerek veritabanı güvenliğinizi bir üst seviyeye taşıyabilirsiniz.

Bu kuralları projelerinizde uygulamaya başladığınızda, veri tutarlılığının ne kadar arttığını ve hata ayıklama süreçlerinizin ne kadar kolaylaştığını fark edeceksiniz. Başarılar dilerim.

Bu yazıya tepkinizi paylaşın:
Kerem Tekin

Teknoloji ve yazılım kullanımı üzerine pratik kılavuzlar hazırlıyorum. Karmaşık dijital araçları, herkesin hızlıca öğrenebileceği sade rehberler haline getirmekte uzmanım.

Yorumlar (0)

Yorum Yaz