İçeriğe geç
Educora
Üniversite25 dk56 / 59

Veri tabanı kuramı

İlişkisel modeli, anahtarları, fonksiyonel bağımlılıkları, adım adım bir örnekle 1NF–3NF normalizasyonunu, işlemleri (transaction) ve ACID'i, indeksleri ve SQL ile NoSQL farkını öğren.

Kendini test et
Bu derste öğreneceklerin
  • 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.

π[first_name](σ[city = 'Bakı'](students)) ≡ SELECT first_name FROM students WHERE city = 'Bakı'
burada:
  • σseçme (selection): koşulu sağlayan satırlar — WHERE
  • πizdüşüm (projection): gereken sütunlar — SELECT listesi
  • ⋈birleştirme (join): iki ilişkiyi ortak nitelik üzerinden birleştirme — JOIN
AnahtarTanımÖrnek (students)
Süper anahtarbir satırı tek başına belirleyen herhangi bir nitelik kümesi{id}, {id, city}
Aday anahtaren küçük süper anahtar (hiçbir nitelik çıkarılamaz){id}
Birincil anahtarseçilen aday anahtar: benzersiz ve asla NULL değilid
Yabancı anahtarbaşka bir tablonun birincil anahtarına başvuru (bilgi bütünlüğü)enrollments.student_id → students.id
SQL
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
Anahtar adaylarını veriyle sınıyoruz: 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.

Tanım
Fonksiyonel bağımlılık X → Y

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.

FormKoşulNeyi giderir
1NFher hücrede tek atomik değer, yinelenen grup yok“Laptop, Kulaklık” gibi liste hücreleri
2NF1NF + hiçbir anahtar olmayan nitelik bileşik anahtarın bir kısmına bağlı değilkısmi bağımlılıklar
3NF2NF + anahtar olmayan nitelikler yalnızca anahtara bağlı, birbirine değilgeçişli bağımlılıklar
3NF'nin akılda kalan özeti: anahtar olmayan her nitelik “anahtara, anahtarın tamamına ve anahtardan başka hiçbir şeye” bağlı olmalıdır.
Örnek 1: bir sipariş tablosunu 3NF'ye getirmek

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
1NF: listeyi açarız; her (sipariş, ürün) için bir satır:
(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.
SQL
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
Örnek veri tabanı normalize edilmiştir: 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

ÖzellikAnlamıNasıl sağlanır
Bölünmezlik (A)ya hepsi ya hiçbiriROLLBACK, geri alma günlüğü
Tutarlılık (C)veri tabanı bir geçerli durumdan diğerine geçerkısıtlar: anahtarlar, CHECK, yabancı anahtarlar
Yalıtım (I)eş zamanlı işlemler birbirinin yarım kalmış işini görmezkilitler, ç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)
SQL
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
Uygulamada bölünmezlik: işlem stoktan 2 dizüstü bilgisayar düştü ve bir sipariş yazdı, sonra iptal edildi (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

h = ⌈log N / log f⌉h = ⌈log N / log f⌉
burada:
  • 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ı
Örnek 2: indeksin kazancı

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
İndekssiz, yani tam tarama: 10⁷ / 100 = 10⁵ sayfa.
İ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çütSQL (ilişkisel)NoSQL
modeltablolar ve ilişkilerbelge, anahtar–değer, geniş sütun, graf
şemakatı, önceden tanımlıesnek
işlemlertam 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)
örneklerPostgreSQL, MySQL, SQLite, SQL ServerMongoDB, Redis, Cassandra, Neo4j
Seçim göreve bağlıdır: banka hesapları için SQL, oturum önbelleği için Redis, sosyal bağlantılar için graf veri tabanı. Birçok proje ikisini birlikte kullanır.

Ö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.

1 / 10
grades(student_id, course_id, student_name, score), anahtar (student_id, course_id) ve student_id → student_name. Tablo hangi normal formu ihlal ediyor?