Berk Akademi
Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

SQL’de ON DELETE CASCADE Ne Zaman Risklidir? Örnekli Rehber

sqlde-on-delete-cascade-ne-zaman-risklidir-ornekli-rehber
Bu yazıda neler var?
  1. ON DELETE CASCADE ne işe yarar? Parent-child ilişkide temel mantık
  2. CASCADE, RESTRICT ve SET NULL nasıl ayrılır?
  3. SQL örneği: Parent silinince hangi child satırları gider?
  4. ON DELETE CASCADE ne zaman kolaylık, ne zaman risk?
  5. Silmeden önce güvenli kontrol listesi: SELECT ve izole test
  6. Sık Sorulan Sorular

ON DELETE CASCADE, bir parent satırı silindiğinde ona foreign key ile bağlı child satırlarının da otomatik olarak silinmesini sağlayan ilişki davranışıdır. Ancak bu işlem her ilişkide kendiliğinden gerçekleşmez; yalnızca ilgili foreign key tanımında ON DELETE CASCADE seçilmişse uygulanır.

Bu nedenle parent satırını silerken yalnızca tek bir satırın gideceğini varsaymak tehlikelidir. İlişkili child kayıtlarının da otomatik silinip silinmeyeceği, veritabanı şemasında seçilen davranışa bağlıdır.

ON DELETE CASCADE ne işe yarar? Parent-child ilişkide temel mantık

İlişkisel veritabanlarında parent, başka tablolar tarafından referans verilen ana kaydı; child ise bu kayda bağlı olan kaydı ifade eder. Örneğin users tablosunda kullanıcılar, orders tablosunda ise bu kullanıcıların siparişleri tutulabilir.

Bu örnekte users.id parent taraftaki anahtar, orders.user_id ise child taraftaki bağlantı alanıdır. Child tablodaki bu alanın parent tablodaki bir kayda işaret etmesini sağlayan kurala foreign key denir. Böylece hangi siparişin hangi kullanıcıya ait olduğu veritabanı düzeyinde tanımlanır.

İlişki ON DELETE CASCADE ile tanımlanmışsa, örneğin users.id = 42 olan kullanıcı silindiğinde orders.user_id = 42 olan siparişler de otomatik olarak silinir. Yani silme işlemi yalnızca users tablosundaki parent satırına dokunmaz; seçilen ilişki davranışı doğrultusunda bağlı child satırlarını da etkiler.

Bu davranış, child kaydın parent olmadan anlamlı olmadığı durumlarda kullanışlıdır. Bir siparişin kendisine ait kullanıcı kaydı olmadan sistemde tutulması anlamsızsa, kullanıcı silindiğinde o kullanıcıya bağlı siparişlerin de kaldırılması veri bütünlüğünü koruyabilir. Buna karşılık siparişlerin yasal kayıt, raporlama veya geçmiş takibi amacıyla saklanması gerekiyorsa otomatik silme uygun olmayabilir.

CASCADE, RESTRICT ve SET NULL nasıl ayrılır?

CASCADE, RESTRICT ve SET NULL nasıl ayrılır?

Bu üç seçenek, parent satırı silinmek istendiğinde child kayıtlarına nasıl davranılacağını belirler. CASCADE bağlı child satırlarını kaldırır; RESTRICT bağlı child satırlar dururken parent silme işlemini engeller; SET NULL ise child satırını koruyup bağlantı alanını NULL yapar.

Seçenek Parent silme denemesinde davranış Child satırının sonucu Anlamlı kullanım
CASCADE Parent silinir; yalnızca parent satırı silinmez. Bağlı child satırları otomatik olarak silinir. Child kayıt parent olmadan anlamlı değilse
RESTRICT Bağlı child satırlar varsa parent silme işlemi reddedilir. Child satırlar değişmeden kalır. Yanlışlıkla silmeyi önlemek ve kayıtları korumak için
SET NULL Parent silinebilir; bağlantı alanının boş kalmasına izin verilmelidir. Child satırı korunur, foreign key alanı NULL olur. İlişki isteğe bağlıysa veya child kayıt korunacaksa

SET NULL kullanılabilmesi için child tablodaki ilgili foreign key sütununun NULL kabul etmesi gerekir. Ayrıca NULL değerinin uygulama açısından anlamlı olması önemlidir: Bu değer, child kaydın artık bir parent kayda bağlı olmadığını veya ilişkinin isteğe bağlı olduğunu temsil edebilir. Sütun NOT NULL olarak tanımlanmışsa bu davranış uygulanamaz.

SQL örneği: Parent silinince hangi child satırları gider?

SQL örneği: Parent silinince hangi child satırları gider?

Bu örnekte users parent, orders ise child tablodur. orders.user_id alanı, users.user_id alanına foreign key ile bağlanır. İlişkiye ON DELETE CASCADE eklendiği için bir kullanıcı silindiğinde, o kullanıcıya bağlı sipariş satırları da otomatik olarak silinir.

Aşağıdaki kod genel SQL sözdizimiyle hazırlanmıştır. Çalıştırmadan önce kullandığın SQL lehçesinde CREATE TABLE, foreign key kısıtı ve ON DELETE CASCADE davranışını kontrol etmelisin.

CREATE TABLE users (
    user_id INTEGER PRIMARY KEY,
    user_name VARCHAR(100) NOT NULL
);

CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    user_id INTEGER NOT NULL,
    order_total DECIMAL(10, 2) NOT NULL,

    CONSTRAINT fk_orders_users
        FOREIGN KEY (user_id)
        REFERENCES users (user_id)
        ON DELETE CASCADE
);

INSERT INTO users (user_id, user_name) VALUES
    (1, 'Ayşe'),
    (2, 'Mehmet');

INSERT INTO orders (order_id, user_id, order_total) VALUES
    (101, 1, 250.00),
    (102, 1, 80.00),
    (103, 2, 145.00);

Silme işleminden önce siparişleri incelediğinde beklenen çıktı şöyledir:

SELECT order_id, user_id, order_total
FROM orders
ORDER BY order_id;

order_id | user_id | order_total
---------+---------+------------
101      | 1       | 250.00
102      | 1       | 80.00
103      | 2       | 145.00

Şimdi yalnızca izole örnek veritabanında, user_id = 1 olan kullanıcıyı silelim:

DELETE FROM users
WHERE user_id = 1;

Silme sonrasında users tablosunda Mehmet kalır. orders tablosunda ise Ayşe’ye bağlı 101 ve 102 numaralı siparişler artık bulunmaz:

SELECT user_id, user_name
FROM users
ORDER BY user_id;

user_id | user_name
--------+----------
2       | Mehmet


SELECT order_id, user_id, order_total
FROM orders
ORDER BY order_id;

order_id | user_id | order_total
---------+---------+------------
103      | 2       | 145.00

Yani tek bir parent satırını silmek, ona bağlı birden fazla child satırını etkileyebilir. Bu nedenle örnekteki komut üretim veritabanında doğrudan çalıştırılmamalıdır; önce hangi kayıtların etkileneceği incelenmeli ve davranış izole bir ortamda denenmelidir.

ON DELETE CASCADE ne zaman kolaylık, ne zaman risk?

CASCADE, parent olmadan anlamını korumayan child kayıtlar için pratik bir seçim olabilir. Örneğin yalnızca bir sepetin içeriğini temsil eden geçici satırlar, taslak kayıtlar veya iki tablo arasındaki ilişkiyi tutan ara kayıtlar parent silindiğinde otomatik olarak kaldırılabilir.

Buna karşılık tarihçe, denetim kayıtları, fatura ve ödeme bilgileri gibi veriler parent silinse bile kendi anlamını koruyabilir. Bu tür kayıtlarda otomatik silme, fark edilmesi zor ve geri dönüşü olmayan veri kayıplarına yol açabilir. Bu yüzden CASCADE her zaman tehlikeli veya her zaman güvenli değildir; karar, verinin iş anlamına göre verilmelidir. PostgreSQL belgeleri de bağımsız olmayan bileşenlerde CASCADE seçeneğinin uygun olabileceğini, bağımsız nesnelerde ise silmeyi engelleyen davranışların tercih edilebileceğini belirtir.

  1. Child kayıt parent olmadan anlamlı mı?

    Hayırsa child, parent’ın ayrılmaz bir parçası olabilir ve CASCADE adayıdır. Evetse, örneğin bir denetim kaydı geçmişteki olayı açıklamaya devam ediyorsa otomatik silme yerine RESTRICT veya başka bir koruma yaklaşımı düşünülmelidir.

  2. Parent silinince child da silinmeli mi?

    İş kuralı açıkça “parent silindiğinde bağlı geçici kayıtlar da silinsin” diyorsa CASCADE uygun olabilir. Ancak sipariş, fatura veya ödeme gibi kayıtların korunması gerekiyorsa silmeyi engelleyen RESTRICT daha güvenli bir tercih olabilir.

  3. Child parent olmadan yaşayabiliyor mu?

    Child kaydının parent ilişkisi isteğe bağlıysa ve kayıt korunacaksa, foreign key alanını NULL yaparak ilişkiyi kaldıran SET NULL değerlendirilebilir. Child yaşayamıyorsa iki farklı iş kuralı ortaya çıkar: kayıt da silinecekse CASCADE, parent’ın silinmesi engellenecekse RESTRICT.

Bu üç soru otomatik karar veren bir formül değildir. Ama veri modelini, kayıtların yaşam döngüsünü ve silme işleminin iş kuralıyla uyumunu sorgulamak için güçlü bir değerlendirme çerçevesi sunar.

Silmeden önce güvenli kontrol listesi: SELECT ve izole test

ON DELETE CASCADE tanımlı olsa bile silme işleminden önce hangi parent kaydının ve hangi child satırlarının etkileneceğini görmelisin. Özellikle kullanıcı-sipariş gibi ilişkilerde aşağıdaki kontrol listesi, geri dönüşü zor bir hatayı önlemeye yardımcı olur.

  1. Silinecek parent kimliğini netleştir. Kullanıcıyı yalnızca adıyla değil, benzersiz kimliğiyle belirle. Örneğin users.id = 42 kaydını incelemeden önce bu kimliğin doğru kullanıcıya ait olduğunu doğrula.
  2. İlişkili child tablolarını belirle. Kullanıcıya bağlı sipariş, adres, yorum veya başka kayıtlar bulunup bulunmadığını listele. Yalnızca doğrudan bağlı tabloyu değil, ilişkiler zincirindeki diğer tabloları da dikkate al.
  3. SELECT ile etkilenecek satırları incele. Kullanıcıya bağlı siparişleri görmek için örneğin şu sorguyu çalıştırabilirsin. Tablo ve sütun adları, kendi şemana göre değişebilir:
SELECT
    o.id,
    o.user_id,
    o.created_at,
    o.status,
    o.total_amount
FROM orders AS o
WHERE o.user_id = 42
ORDER BY o.created_at;

Bu sorgu, parent silinirse CASCADE kuralı nedeniyle etkilenebilecek siparişleri görmeni sağlar. Siparişlerin yalnızca teknik bağımlılık taşıyan satırlar mı, yoksa tarihçe ve raporlama açısından korunması gereken bağımsız kayıtlar mı olduğunu ayrıca değerlendir.

  1. Üç soruluk karar çerçevesini kullan. Child kayıt parent olmadan anlamlı mı? Parent silinince child da silinmeli mi? Child parent olmadan yaşayabiliyor mu? Yanıtlar, CASCADE yerine RESTRICT veya SET NULL gibi başka bir davranışın daha uygun olup olmadığını gösterebilir.
  2. İzole bir veritabanında deneme yap. Bilinen örnek kullanıcı, sipariş ve ilişkili child kayıtları oluştur. Aynı örnek veri üzerinde CASCADE, RESTRICT ve SET NULL davranışlarını gözlemle. Beklenen satırların silindiğini, korunduğunu veya ilişki alanının boş kaldığını kontrol et.
  3. Kararı dokümante et. Hangi parent kaydının neden silinebileceğini, hangi child kayıtlarının etkileneceğini ve seçilen foreign key davranışının gerekçesini yazılı hâle getir. Üretim veritabanında, inceleme tamamlanmadan geri dönüşsüz bir DELETE komutu çalıştırma.

Sık Sorulan Sorular

ON DELETE CASCADE parent silinince child kayıtlarını neden otomatik kaldırır?

Bu kural, parent-child ilişkisindeki bağımlılığı veritabanına bildirir. Parent kayıt silindiğinde ona bağlı child kayıtları da otomatik kaldırılarak artık karşılığı olmayan ilişkilerin kalması önlenir.

RESTRICT kullanıldığında bağlı child kayıtları bulunan parent silinebilir mi?

Genellikle hayır. Bağlı child kayıtları varken parent silme işlemi reddedilir. Önce child kayıtlarının nasıl ele alınacağına karar verilmesi gerekir.

SET NULL kullanmak için child tablosundaki ilişki alanı neden NULL kabul etmelidir?

Çünkü parent silindiğinde foreign key alanına boş değer yazılır. Bu alan NOT NULL olarak tanımlanmışsa veritabanı ilişkiyi boş bırakamaz ve işlem başarısız olur.

Silme öncesinde etkilenecek child kayıtlarını nasıl kontrol edebilirim?

Parent kimliğini filtreleyen bir SELECT sorgusuyla bağlı child satırlarını listeleyebilirsin. Ardından bu kayıtların tarihçe, raporlama veya bağımsız kullanım açısından korunması gerekip gerekmediğini değerlendirmelisin.

Güvenli silme kararının temeli, komutu çalıştırmak değil; etkilenecek ilişkileri önceden görüp verinin anlamını doğru değerlendirmektir.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara