- Süper, aday, birincil ve yabancı anahtarları ayırt etmek
- Fonksiyonel bağımlılıklara göre bir tabloyu 3NF'ye kadar normalize etmek
- ACID özelliklerini açıklamak ve bir indeksin kazancını hesaplamak
Bir çevrim içi mağaza her siparişi tek bir tablo satırına yazsaydı, Anar Bakü'den Gence'ye taşındığında adresinin yüzlerce satırda değiştirilmesi gerekirdi; birini unutursan veri tabanında iki farklı şehir kalırdı. Veri tabanı kuramı bu tür sorunları matematiksel kesinlikle ortadan kaldırır: veriyi doğru tablolara ayırır, aynı anda çalışan yüzlerce kullanıcıya karşı korur ve milyarlarca satır arasında aramayı milisaniyelere indirir.
İlişkisel model ve anahtarlar
Edgar Codd'un 1970'te önerdiği ilişkisel modelde veriler ilişkilerde (tablolarda) saklanır. Bir ilişki, aynı niteliklere sahip demetlerin (satırların) kümesidir; her niteliğin bir etki alanı (izin verilen değerler kümesi) vardır. Küme olduğu için satırların sırası yoktur ve iki aynı satır bulunamaz. Sorgular ilişkisel cebirle ifade edilir; SQL onun pratik dilidir.
- σseçme (selection): koşulu sağlayan satırlar —
WHERE - πizdüşüm (projection): gereken sütunlar —
SELECTlistesi - ⋈birleştirme (join): iki ilişkiyi ortak nitelik üzerinden birleştirme —
JOIN
| Anahtar | Tanım | Örnek (students) |
|---|---|---|
| Süper anahtar | bir satırı tek başına belirleyen herhangi bir nitelik kümesi | {id}, {id, city} |
| Aday anahtar | en küçük süper anahtar (hiçbir nitelik çıkarılamaz) | {id} |
| Birincil anahtar | seçilen aday anahtar: benzersiz ve asla NULL değil | id |
| Yabancı anahtar | başka bir tablonun birincil anahtarına başvuru (bilgi bütünlüğü) | enrollments.student_id → students.id |
SELECT COUNT(*) AS students,
COUNT(email) AS with_email,
COUNT(DISTINCT email) AS distinct_emails,
COUNT(DISTINCT city) AS distinct_cities
FROM students;▸ Beklenen çıktı
students | with_email | distinct_emails | distinct_cities 12 | 10 | 10 | 7
city anahtar olamaz (12 satırda yalnızca 7 farklı şehir). email dolu olduğu satırlarda benzersizdir (10 = 10) ama 2 öğrencide NULL'dır; bu yüzden birincil anahtar olamaz. Dikkat: mevcut veri bir anahtarı asla kanıtlamaz; anahtar bir iş kuralıdır.Normalizasyon: 1NF, 2NF, 3NF
Kötü tasarlanmış bir tablo üç tür anomali üretir. Güncelleme anomalisi: aynı bilgi birçok satırda yinelenir ve biri güncellenmezse veriler çelişir. Ekleme anomalisi: henüz siparişi olmayan yeni bir ürün kaydedilemez, çünkü anahtarın bir kısmı boş kalır. Silme anomalisi: bir müşterinin tek siparişini silersen müşteriyle ilgili tüm bilgiler de kaybolur. Normalizasyon, tabloyu bilgi kaybetmeden parçalara ayırarak bu anomalileri giderir: her bilgi tek bir yerde saklanır.
X nitelikleri aynı olan iki satırın Y nitelikleri de mutlaka aynıdır. Örneğin customer_id → customer_city: müşteriyi bilirsen şehrini de bilirsin. Normalizasyon tam olarak bu bağımlılıklara dayanır.
| Form | Koşul | Neyi giderir |
|---|---|---|
| 1NF | her hücrede tek atomik değer, yinelenen grup yok | “Laptop, Kulaklık” gibi liste hücreleri |
| 2NF | 1NF + hiçbir anahtar olmayan nitelik bileşik anahtarın bir kısmına bağlı değil | kısmi bağımlılıklar |
| 3NF | 2NF + anahtar olmayan nitelikler yalnızca anahtara bağlı, birbirine değil | geçişli bağımlılıklar |
Bir mağaza tablosu: order_id, order_date, customer_id, customer_name, customer_city, products; products hücresinde fiyat ve kategorilerle birlikte “Laptop ×1, Headphones ×2” gibi bir liste var. Tabloyu 1NF, 2NF ve 3NF'ye getir.
Çözümü gösterÇözümü gizle
(order_id, product_id, order_date, customer_id, customer_name, customer_city, product_name, category, price, quantity), anahtar (order_id, product_id).Bağımlılıklar: order_id → order_date, customer_id; customer_id → customer_name, customer_city; product_id → product_name, category, price; (order_id, product_id) → quantity.
2NF: anahtarın bir kısmına bağlı olanları ayırırız:
order_items(order_id, product_id, quantity)orders(order_id, order_date, customer_id, customer_name, customer_city)products(product_id, product_name, category, price)3NF:
orders'ta order_id → customer_id → customer_city geçişlidir, ayırırız:orders(order_id, order_date, customer_id) + customers(customer_id, customer_name, customer_city).Sonuç: 4 tablo. Artık Anar'ın şehri tek bir hücrede değişir.
SELECT s.first_name, s.city, c.title, c.teacher, e.score
FROM enrollments AS e
JOIN students AS s ON s.id = e.student_id
JOIN courses AS c ON c.id = e.course_id
WHERE c.teacher = 'Ramin Səfərov'
ORDER BY c.title, s.first_name;▸ Beklenen çıktı
first_name | city | title | teacher | score Aysel | Bakı | Algebra | Ramin Səfərov | 92 Fidan | Naxçıvan | Algebra | Ramin Səfərov | 97 Murad | Gəncə | Algebra | Ramin Səfərov | 75 Nigar | Şəki | Algebra | Ramin Səfərov | 85 Leyla | Bakı | Geometry | Ramin Səfərov | 95 Orxan | Sumqayıt | Geometry | Ramin Səfərov | 70 Səbinə | Quba | Geometry | Ramin Səfərov | 79
students, courses, enrollments. JOIN “düz” tabloyu yalnızca gerektiğinde yeniden kurar; burada öğretmenin adı 7 kez yineleniyor. Tablo böyle saklansaydı öğretmenin değişmesi 7 satırın güncellenmesini gerektirirdi (güncelleme anomalisi).İşlemler (transaction) ve ACID
| Özellik | Anlamı | Nasıl sağlanır |
|---|---|---|
| Bölünmezlik (A) | ya hepsi ya hiçbiri | ROLLBACK, geri alma günlüğü |
| Tutarlılık (C) | veri tabanı bir geçerli durumdan diğerine geçer | kısıtlar: anahtarlar, CHECK, yabancı anahtarlar |
| Yalıtım (I) | eş zamanlı işlemler birbirinin yarım kalmış işini görmez | kilitler, çok sürümlü eşzamanlılık (MVCC) |
| Kalıcılık (D) | COMMIT'ten sonra veri elektrik kesintisinde bile kalır | önceden yazma günlüğü (WAL) |
BEGIN;
UPDATE products SET stock = stock - 2 WHERE name = 'Laptop';
INSERT INTO orders (customer_id, product_id, quantity, order_date)
VALUES (2, 1, 2, '2025-08-01');
ROLLBACK;
SELECT name, stock,
(SELECT COUNT(*) FROM orders) AS orders_total
FROM products
WHERE name = 'Laptop';▸ Beklenen çıktı
name | stock | orders_total Laptop | 8 | 12
ROLLBACK). İki değişiklik de kayboldu: stok yine 8, sipariş sayısı yine 12. COMMIT yazsaydık ikisi birlikte saklanırdı.Tam yalıtım pahalıdır; bu yüzden SQL dört yalıtım düzeyi sunar. READ UNCOMMITTED “kirli okumaya” (başkasının henüz onaylanmamış değişikliğini görmek), READ COMMITTED “yinelenemeyen okumaya” (aynı satırın iki okumada farklı çıkması), REPEATABLE READ “hayaletlere” (yeni satırların belirmesi) izin verir; SERIALIZABLE ise işlemlerin art arda yürütülmesiyle aynı sonucu garanti eder.
İndeksler, SQL ve NoSQL
- hB-ağacı indeksinin yüksekliği (aramada okunan sayfa sayısı)
- Ntablodaki satır sayısı
- fdallanma: bir sayfaya sığan anahtar sayısı
Bir tabloda N = 10⁷ satır var ve bir disk sayfasına 100 satır sığıyor. WHERE email = … sorgusu indekssiz ve dallanması f = 100 olan bir B-ağacı indeksiyle kaç sayfa okur?
Çözümü gösterÇözümü gizle
İndeksle: h = ⌈log 10⁷ / log 100⌉ = ⌈7/2⌉ = ⌈3,5⌉ = 4 düzey + satırın kendisi için 1 sayfa = ≈ 5 sayfa.
Kazanç ≈ 20.000 kat: O(N) yerine O(log N). Bedeli: indeks yer kaplar ve her INSERT/UPDATE onu da güncellemelidir.
| Ölçüt | SQL (ilişkisel) | NoSQL |
|---|---|---|
| model | tablolar ve ilişkiler | belge, anahtar–değer, geniş sütun, graf |
| şema | katı, önceden tanımlı | esnek |
| işlemler | tam ACID | çoğu zaman sınırlı, “nihai tutarlılık” |
| ölçekleme | çoğunlukla dikey (daha güçlü sunucu) | yatay (çok sayıda sunucu) |
| örnekler | PostgreSQL, MySQL, SQLite, SQL Server | MongoDB, Redis, Cassandra, Neo4j |
Önemli noktalar
- İlişki demetlerin kümesidir; aday anahtar en küçük süper anahtardır, birincil anahtar benzersiz ve NOT NULL'dır, yabancı anahtar bütünlüğü korur.
- 1NF: atomik değerler; 2NF: kısmi bağımlılık yok; 3NF: geçişli bağımlılık yok.
- Normalizasyon güncelleme, ekleme ve silme anomalilerini giderir.
- ACID: bölünmezlik, tutarlılık, yalıtım, kalıcılık; ROLLBACK işlemin tamamını geri alır.
- B-ağacı indeksi aramayı O(N)'den O(log N)'ye indirir ama yazmayı yavaşlatır.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.
grades(student_id, course_id, student_name, score), anahtar (student_id, course_id) ve student_id → student_name. Tablo hangi normal formu ihlal ediyor?