İçeriğe geç
Educora
İleri18 dk12 / 22

İndeksler, görünümler ve işlemler

İndekslerle aramayı hızlandır, görünümlerle karmaşık sorgulara ad ver ve işlemlerle (transaction) değişiklikleri “ya hep ya hiç” ilkesiyle yap.

Kendini test et
Bu derste öğreneceklerin
  • İndeksin ne işe yaradığını açıklamak ve CREATE INDEX ile oluşturmak
  • CREATE VIEW ile görünüm oluşturmak ve onu bir tablo gibi kullanmak
  • BEGIN, COMMIT, ROLLBACK ile işlemleri yönetmek ve ACID kavramını anlamak

Bir milyon kitabı olan ama kataloğu olmayan bir kütüphane düşün: bir kitabı bulmak için her rafa bakman gerekirdi. Büyük bir veritabanı da farklı değildir. Bu derste gerçek projelerin üç önemli aracını öğreneceğiz: aramayı hızlandıran indeksler, sorgulara ad veren görünümler ve verileri kazalardan koruyan işlemler (transaction).

İndeksler

İndeks olmadan WHERE city = 'Bakı' sorgusunda VTYS tablonun her satırını denetler (tam tarama). İndeks, bir sütunun değerlerini sıralı biçimde tutar ve her değerin hangi satırlarda olduğunu bilir; tıpkı bir ders kitabının sonundaki konu dizini gibi. Böylece VTYS doğrudan gereken satırlara gider. EXPLAIN QUERY PLAN, SQLite'ın bir sorguyu nasıl çalıştıracağını gösterir.

SQL
EXPLAIN QUERY PLAN
SELECT first_name FROM students WHERE city = 'Bakı';
▸ Beklenen çıktı
id | parent | notused | detail
2 | 0 | 216 | SCAN students
İndeks yok: SCAN — tablonun tamamı okunur. Önemli olan detail sütunudur; diğer sayılar sürüme göre değişebilir.
SQL
CREATE INDEX idx_students_city ON students (city);

EXPLAIN QUERY PLAN
SELECT first_name FROM students WHERE city = 'Bakı';
▸ Beklenen çıktı
id | parent | notused | detail
3 | 0 | 62 | SEARCH students USING INDEX idx_students_city (city=?)
İndeksle: SEARCH ... USING INDEX — yalnızca gereken satırlar okunur.

PRIMARY KEY ve UNIQUE sütunları için VTYS indeksi kendisi oluşturur. CREATE UNIQUE INDEX hem aramayı hızlandırır hem de tekrarlanan değerleri yasaklar. Aşağıda Aysel'in e-postasıyla ikinci bir öğrenci eklemek başarısız olur.

SQL
CREATE UNIQUE INDEX idx_students_email ON students (email);

INSERT INTO students (first_name, last_name, email)
VALUES ('Test', 'User', 'aysel@example.com');
▸ Beklenen çıktı
Error: UNIQUE constraint failed: students.email

Görünümler (VIEW)

Tanım
Görünüm (view)

Adı olan, kaydedilmiş bir sorgu. Ondan bir tablo gibi SELECT yapılabilir, ama kendi verisini saklamaz: her seferinde temel tablolardan yeniden hesaplanır.

Üç tablolu bir JOIN sorgusunu her seferinde yeniden yazmak yorucudur. Onu bir kez student_scores görünümü olarak kaydedelim; sonrasında sorgular çok basitleşir.

SQL
CREATE VIEW student_scores AS
SELECT s.first_name || ' ' || s.last_name AS student,
       c.title AS course,
       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;

SELECT student, course, score
FROM student_scores
WHERE score >= 93
ORDER BY score DESC;
▸ Beklenen çıktı
student | course | score
Rəşad Kərimov | Python Basics | 99
Fidan Cəfərova | Algebra | 97
Leyla Hüseynova | Geometry | 95
Fidan Cəfərova | Mechanics | 94
Nigar Rzayeva | World History | 93
SQL
CREATE VIEW student_scores AS
SELECT s.first_name || ' ' || s.last_name AS student,
       c.title AS course,
       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;

SELECT course, COUNT(*) AS students, MAX(score) AS best
FROM student_scores
GROUP BY course
ORDER BY best DESC
LIMIT 3;
▸ Beklenen çıktı
course | students | best
Python Basics | 3 | 99
Algebra | 4 | 97
Geometry | 3 | 95
Bir görünümle sıradan bir tablo gibi çalışılabilir: WHERE, GROUP BY, ORDER BY ve hatta JOIN.

İşlemler (transaction)

Aysel'in hesabından Murad'ın hesabına 30 manat aktarmak iki komuttur: birinden düşmek, diğerine eklemek. İlk komuttan sonra elektrik kesilirse para ortadan kaybolur! İşlem (transaction), birkaç komutu bölünmez tek bir iş olarak birleştirir: ya hepsi uygulanır (COMMIT) ya da hiçbiri (ROLLBACK).

SQL
CREATE TABLE accounts (
  id      INTEGER PRIMARY KEY,
  owner   TEXT NOT NULL,
  balance INTEGER NOT NULL CHECK (balance >= 0)
);
INSERT INTO accounts (owner, balance) VALUES ('Aysel', 100), ('Murad', 50);

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 30 WHERE owner = 'Aysel';
UPDATE accounts SET balance = balance + 30 WHERE owner = 'Murad';
COMMIT;

SELECT owner, balance FROM accounts ORDER BY id;
▸ Beklenen çıktı
owner | balance
Aysel | 70
Murad | 80
COMMIT iki değişikliği birlikte onaylar. Aysel'den 150 manat düşmeye çalışsaydık CHECK kısıtlaması komutu reddederdi, program da aktarımın tamamını ROLLBACK ile iptal ederdi.

ROLLBACK, BEGIN komutundan sonra yapılan tüm değişiklikleri geri alır. Aşağıda yanlışlıkla tüm siparişleri siliyoruz, ama bir işlemin içinde olduğumuz için ROLLBACK hepsini geri getiriyor.

SQL
BEGIN TRANSACTION;
DELETE FROM orders;                      -- oops, no WHERE!
SELECT COUNT(*) AS inside FROM orders;   -- 0 inside the transaction
ROLLBACK;                                -- undo everything since BEGIN

SELECT COUNT(*) AS after_rollback FROM orders;
▸ Beklenen çıktı
after_rollback
12
HarfÖzellikAnlamı
AAtomicitybölünmezlik: ya hep ya hiç
CConsistencytutarlılık: işlemden sonra tüm kurallar (kısıtlamalar) sağlanır
IIsolationyalıtım: aynı anda çalışan işlemler birbirini etkilemez
DDurabilitykalıcılık: onaylanan değişiklik bir çökmeden sonra da korunur
ACID — güvenilir işlemlerin dört özelliği.
VTYSİşlemi başlatmaSorgu planı
SQLiteBEGIN TRANSACTIONEXPLAIN QUERY PLAN
MySQLSTART TRANSACTIONEXPLAIN
PostgreSQLBEGINEXPLAIN
SQL ServerBEGIN TRANSACTIONyürütme planı (Execution Plan)
COMMIT ve ROLLBACK hepsinde aynıdır.
Alıştırma

Her şehirdeki öğrenci sayısını (students) gösteren city_stats görünümünü oluştur. Sonra bu görünümden en az 2 öğrencisi olan şehirleri seç: öğrenci sayısına göre azalan, eşitlikte şehir adına göre artan sırada.

Alıştırma · SQL
CREATE VIEW city_stats AS
-- the query that counts students per city
;

SELECT city, students
FROM city_stats
-- keep cities with at least 2 students and sort
▸ Beklenen çıktı
city | students
Bakı | 4
Gəncə | 2
Sumqayıt | 2
Alıştırma

Bir satışı tek bir işlemde kaydet: 5 numaralı müşteri 2025-08-01 tarihinde 3 numaralı üründen (Headphones) 2 adet alıyor. Siparişi orders tablosuna ekle, ürünün stoğunu 2 azalt ve COMMIT yap. Sonra Headphones için adı, stoğu (stock) ve sipariş sayısını (orders) göster.

Alıştırma · SQL
BEGIN TRANSACTION;
-- INSERT the order
-- UPDATE the stock
COMMIT;

SELECT name,
       stock,
       (SELECT COUNT(*) FROM orders WHERE product_id = 3) AS orders
FROM products
WHERE id = 3;
▸ Beklenen çıktı
name | stock | orders
Headphones | 38 | 3

Önemli noktalar

  • İndeks aramayı hızlandırır ama yer kaplar ve yazmayı yavaşlatır.
  • CREATE UNIQUE INDEX hem hız kazandırır hem de tekrarları yasaklar.
  • Görünüm (CREATE VIEW), bir tablo gibi kullanılan, adı olan kaydedilmiş bir sorgudur.
  • İşlem: BEGIN → komutlar → COMMIT (onayla) ya da ROLLBACK (geri al).
  • ACID: bölünmezlik, tutarlılık, yalıtım, kalıcılık.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
İndeks ne işe yarar?