Neden kısıt?
Uygulama kodu değişir, farklı ekipler aynı tabloya yazar; ama kısıtlar her zaman çalışır. Bozuk veri bir kez girdiğinde temizlemek, girmesini engellemekten çok daha pahalıdır.
| Kısıt | Ne sağlar? |
|---|---|
NOT NULL | Değer boş olamaz |
UNIQUE | Değer tekrar edemez (NULL'lar çoğu SQL türünde birden fazla olabilir) |
PRIMARY KEY | NOT NULL + UNIQUE; satırın kimliği |
CHECK (koşul) | Koşulu sağlamayan değer reddedilir |
DEFAULT | Değer verilmezse kullanılacak varsayılan (kısıt değil, sütun özelliği) |
FOREIGN KEY | Değer başka tablodaki bir anahtarda bulunmalı |
CREATE TABLE kampanya ( kampanya_id INTEGER PRIMARY KEY, kod TEXT NOT NULL UNIQUE, indirim REAL NOT NULL CHECK (indirim > 0 AND indirim <= 0.5), baslangic TEXT NOT NULL, bitis TEXT NOT NULL, aktif INTEGER DEFAULT 1, CHECK (bitis >= baslangic) ); INSERT INTO kampanya (kampanya_id, kod, indirim, baslangic, bitis) VALUES (1, 'YILBASI', 0.2, '2024-12-20', '2025-01-05'); SELECT * FROM kampanya;
-- CHECK ihlali: indirim %60 olamaz INSERT INTO kampanya (kampanya_id, kod, indirim, baslangic, bitis) VALUES (2, 'HATA', 0.6, '2024-12-01', '2024-12-10');
Yabancı anahtar eylemleri
Ana tablodaki bir satır silinince veya anahtarı değişince alt tablodaki satırlara ne olacağını belirler:
| Eylem | Davranış |
|---|---|
NO ACTION / RESTRICT (varsayılan) | Bağlı satır varsa silme reddedilir |
ON DELETE CASCADE | Bağlı satırlar da silinir (sipariş silinince satırları) |
ON DELETE SET NULL | Bağlı satırların yabancı anahtarı NULL olur (yönetici ayrılınca) |
ON DELETE SET DEFAULT | Varsayılan değere döner (her SQL türünde yok) |
CREATE TABLE siparis_satiri (
satir_id INT PRIMARY KEY,
siparis_id INT NOT NULL,
CONSTRAINT fk_satir_siparis FOREIGN KEY (siparis_id)
REFERENCES siparis (siparis_id) ON DELETE CASCADE
);
-- Kısıtı sonradan eklemek ve kaldırmak
ALTER TABLE products ADD CONSTRAINT ck_fiyat CHECK (price >= cost);
ALTER TABLE products DROP CONSTRAINT ck_fiyat;
SQL türlerine göreMySQL CHECK kısıtını 8.0.16'dan beri uygular; daha eski sürümler sessizce yok sayardı. Oracle'da NOT NULL yalnızca sütun düzeyinde (inline) yazılabilir ve kısıtlar
DEFERRABLE yapılarak işlem sonunda denetlenebilir. BigQuery'de PRIMARY/FOREIGN KEY yalnızca bilgi amaçlıdır (NOT ENFORCED), UNIQUE ve CHECK yoktur.Kısıtlara ad ver
CONSTRAINT ck_fiyat CHECK (...) gibi adlandırılmış kısıtlar hata mesajlarında anlaşılır görünür ve kolayca kaldırılır.Yabancı anahtarı gerçekten denemek
Bu motordaYabancı anahtar, yalnız aynı çalıştırmada
FOREIGN KEY ya da REFERENCES içeren bir tablo oluşturursan denetlenir. Yoksa denetim kapalıdır: hazır veri setlerinde DELETE FROM customers hatasız geçer ve yetim satır bırakır; alıştırmalar bu yüzden bozulmasın diye böyledir. Gerçek sunucuda aynı silme reddedilir. MySQL satır içi REFERENCES yazımını yok sayar, orada tablo düzeyinde FOREIGN KEY yazılır; bu yüzden kutular MySQL'de kapalı.CREATE TABLE siparis (siparis_id INTEGER PRIMARY KEY); CREATE TABLE satir (satir_id INTEGER PRIMARY KEY, siparis_id INTEGER NOT NULL REFERENCES siparis (siparis_id)); INSERT INTO siparis VALUES (1); INSERT INTO satir VALUES (10, 1); -- Bağlı satır varken ana satır silinemez DELETE FROM siparis WHERE siparis_id = 1;
CREATE TABLE siparis (siparis_id INTEGER PRIMARY KEY); CREATE TABLE satir (satir_id INTEGER PRIMARY KEY, siparis_id INTEGER NOT NULL REFERENCES siparis (siparis_id) ON DELETE CASCADE); INSERT INTO siparis VALUES (1); INSERT INTO satir VALUES (10, 1); INSERT INTO satir VALUES (11, 1); DELETE FROM siparis WHERE siparis_id = 1; SELECT COUNT(*) AS kalan_satir FROM satir;