SQL NEDİR? SELECT, JOİN, INDEX VE TRANSACTİON TEMELLERİ
Veriyle çalışan herkesin bir noktada karşılaştığı ortak soru şudur: “Bu bilgiyi en doğru ve en hızlı şekilde nasıl çekebilirim?” İşte SQL (Structured Query Language), ilişkisel veritabanlarında veriyi okumak, yazmak ve yönetmek için kullanılan standart dil olarak bu soruya pratik bir yanıt sunar.
SQL’i yalnızca “sorgu yazma” becerisi gibi görmek, potansiyelini küçümsemek olur. Doğru yazılmış bir SELECT sorgusu raporlamayı hızlandırır, doğru tasarlanmış JOIN ilişkileri veriyi anlamlı hale getirir, iyi kurgulanmış index yapıları performansı belirgin biçimde iyileştirir. Öte yandan transaction ve tutarlılık kavramları işin güvenilirlik tarafını taşır.
Bu makalede SQL’in temel taşlarını; veri okuma (SELECT), tablo birleştirme (JOIN), performans (index) ve güvenli değişiklik (transaction) ekseninde, gerçekçi örneklerle adım adım ele alacağız. Amaç, ezber değil; mantığı kavrayıp günlük iş akışında uygulayabileceğiniz bir temel oluşturmaktır.

SQL Nedir ve Neden Hâlâ Standart?
SQL, ilişkisel veritabanlarında veriyi tanımlamak (DDL), manipüle etmek (DML) ve sorgulamak (DQL) için kullanılan dildir. Oracle, PostgreSQL, MySQL, SQL Server gibi farklı sistemlerde ufak sözdizimi farkları bulunsa da, SQL’in çekirdeği büyük ölçüde ortaktır. Bu sayede bir veritabanından diğerine geçişte bilgi birikiminiz kolayca taşınır.
SQL’in “standart” oluşu, yalnızca tarihsel bir alışkanlık değildir. İlişkisel modelin güçlü yönleri (tablo yapısı, anahtarlar, kısıtlar ve ilişki yönetimi) kurumsal verinin tutarlı ve denetlenebilir biçimde saklanmasını sağlar. Özellikle finans, e-ticaret, operasyon ve analitik gibi alanlarda doğruluk ve izlenebilirlik temel beklentidir.
İlişkisel modelin kısa özeti
İlişkisel veritabanında veriler tablolarda tutulur; satırlar kayıtları, sütunlar nitelikleri temsil eder. Tablolar arası ilişki çoğunlukla primary key ve foreign key üzerinden kurulur. Bu ilişkiler iyi tasarlanırsa, hem veri tekrarını azaltır hem de sorgularda anlamlı bağlam kurmanızı kolaylaştırır.
SQL ile neyi hedeflersiniz?
- Raporlama ve analiz için güvenilir veri çekimi
- Uygulama ekranları için hızlı ve doğru okuma/yazma işlemleri
- İş kurallarını kısıtlar ve transaction mantığıyla koruma
- Performans sorunlarını ölçme ve iyileştirme
SELECT ile Veri Okuma Mantığı
SQL öğrenirken ilk durak genellikle SELECT olur; çünkü veri okuma, hem analitik hem de uygulama tarafında en sık ihtiyaç duyulan işlemdir. Burada asıl kritik nokta, “her şeyi çekmek” yerine “ihtiyacın olanı doğru filtreyle çekmek” yaklaşımını benimsemektir.
Temel SELECT yapısı: kolon seçimi ve filtre
Kolonları açıkça seçmek, hem okunabilirlik hem de performans açısından iyi bir alışkanlıktır. Gereksiz kolon çekmek ağ trafiğini ve bellek kullanımını artırır. Ayrıca filtreleri mümkün olduğunca erken uygulamak, daha az satır üzerinde işlem yapılmasını sağlar.
SELECT
c.customer_id,
c.full_name,
c.city,
o.order_id,
o.order_date,
o.total_amount
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
WHERE c.city = 'İzmir'
AND o.order_date >= '2026-01-01'
ORDER BY o.order_date DESC;Bu örnekte WHERE kullanımı ile şehir ve tarih filtresi uygulanır; ardından ORDER BY ile sonuçlar sıralanır. Pratikte, rapor ekranlarının büyük kısmı bu mantığın varyasyonlarıdır.
Toplama (aggregation) ve grup bazlı analiz
SQL yalnızca satır satır veri çekmek için değil, aynı zamanda özet üretmek için de kullanılır. GROUP BY, COUNT, SUM ve AVG gibi fonksiyonlar; “kaç sipariş var?”, “toplam ciro nedir?” gibi soruların doğrudan veritabanında yanıtlanmasını sağlar.
SELECT
c.city,
COUNT(o.order_id) AS order_count,
SUM(o.total_amount) AS total_revenue,
AVG(o.total_amount) AS avg_basket
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
WHERE o.order_date BETWEEN '2026-01-01' AND '2026-01-31'
GROUP BY c.city
HAVING SUM(o.total_amount) > 50000
ORDER BY total_revenue DESC;HAVING, grup sonuçlarına filtre uygulamak için kullanılır; WHERE ise satır bazında filtreler. Bu ayrımı netleştirmek, doğru sonuç üretmenin temelidir.
JOIN Türleriyle Tabloları Birleştirmek
İlişkisel veritabanlarının gücü, veriyi tek bir dev tabloda tutmak yerine; anlamlı parçalara ayırıp ilişkilendirmesinden gelir. Bu ilişkileri sorgu tarafında bir araya getiren mekanizma JOIN’dir. JOIN konusunda en büyük risk, yanlış eşleştirme ile veri çoğaltmak veya eksiltmektir.
INNER JOIN: eşleşen kayıtlar
INNER JOIN, iki tabloda da eşleşen kayıtları getirir. Örneğin, yalnızca siparişi olan müşterileri listelemek istiyorsanız iç içe eşleşme yaklaşımı uygundur. Bu, “var olan ilişki”yi temel alır.
LEFT JOIN: soldaki tüm kayıtlar
LEFT JOIN ise soldaki tablodaki tüm kayıtları getirir; sağdaki tabloda eşleşme yoksa ilgili kolonlar NULL olur. “Tüm müşteriler ve varsa sipariş bilgileri” gibi senaryolarda vazgeçilmezdir. Bu yaklaşım, eksik veriyi de görünür kılar.
JOIN performansı ve doğru anahtar seçimi
JOIN performansı, büyük ölçüde ilişki kurulan kolonların seçimine bağlıdır. Doğru anahtarlar (primary key/foreign key) üzerinden birleşim yapmak hem doğru sonuç üretir hem de daha az maliyetlidir. Ayrıca büyük tabloyu filtreleyip sonra join etmek çoğu zaman daha iyi bir stratejidir.
Örneğin, önce tarih aralığı ile siparişleri daraltıp sonra müşteri bilgilerini eklemek, tüm sipariş tarihçesini join edip sonradan filtrelemeye göre daha verimli olabilir. Ancak her veritabanı motoru aynı planı üretmeyebilir; bu nedenle sorgu planı (execution plan) okumayı öğrenmek iyi bir yatırımdır.
Index Nedir? Performans ve Doğru Kullanım
Bir sorgunun yavaş olması çoğu zaman “SQL kötü yazıldı” anlamına gelmez; sıkça asıl sebep, uygun index yapısının olmamasıdır. Index, kabaca bir kitabın dizini gibidir: aradığınız şeyi satır satır taramak yerine, hızlıca doğru sayfaya götürür.
Index ne zaman işe yarar?
Özellikle WHERE, JOIN ve ORDER BY ile sık kullanılan kolonlarda index büyük fark yaratır. Örneğin, müşteri e-postasıyla arama yapılıyor ya da siparişler tarih bazında listeleniyorsa, ilgili kolonlarda doğru index stratejisi sorgu süresini gözle görülür biçimde düşürebilir.
Bileşik (composite) index mantığı
Tek kolon yerine birden fazla kolonu kapsayan bileşik index, belirli sorgu kalıplarında daha etkilidir. Örneğin “city + order_date” gibi birlikte filtrelenen alanlarda, bileşik bir index, iki ayrı index’e göre daha tutarlı sonuç verebilir. Burada kritik nokta, kolon sırasının sorgu alışkanlıklarıyla uyumlu olmasıdır.
Index eklemek her zaman “bedava hız” değildir. Index’ler yazma işlemlerinde (INSERT/UPDATE/DELETE) ek maliyet yaratır ve depolama tüketir. Bu nedenle, sık güncellenen tablolarda kontrolsüz index birikimi ters etki doğurabilir. En doğru yaklaşım; ölçmek, sorgu planını incelemek ve hedefe yönelik iyileştirmedir.

Transaction ve ACID: Tutarlılık Garantisi
Veri sadece hızlı değil, aynı zamanda doğru ve tutarlı olmalıdır. Bir bankacılık transferi, stok düşümü ya da sipariş oluşturma gibi süreçlerde birden çok adım vardır. Bu adımların bir kısmı başarısız olursa sistemin yarım kalmış durumda bırakılmaması gerekir. Burada devreye transaction girer.
ACID neyi garanti eder?
Atomicity: İşlemler ya tamamen olur ya hiç olmaz. Consistency: İş kuralları ve kısıtlar korunur. Isolation: Eşzamanlı işlemler birbirini beklenmedik şekilde etkilemez. Durability: Onaylanan değişiklikler kalıcıdır. Bu dört kavram, transaction yönetiminin omurgasını oluşturur.
COMMIT ve ROLLBACK ile güvenli akış
Aşağıdaki örnek, basit bir stok düşümü ve sipariş kaydı senaryosunu gösterir. Amaç, iki adımın tek bir bütün gibi çalışmasıdır: biri olmazsa diğeri de olmamalı.
BEGIN;
INSERT INTO orders (customer_id, order_date, total_amount)
VALUES (42, CURRENT_DATE, 899.90);
UPDATE products
SET stock = stock - 1
WHERE product_id = 1001
AND stock >= 1;
-- Stok düşmediyse (0 satır etkilendiyse) uygulama tarafında kontrol edilip ROLLBACK çalıştırılabilir.
COMMIT;Gerçek sistemlerde, bu kontroller genellikle uygulama servis katmanında yapılır; ancak transaction sınırlarını iyi belirlemek ve olası hata senaryolarını düşünmek kritik bir beceridir. Özellikle izolasyon seviyesi seçimi, kilitlenme (locking) ve bekleme süreleri üzerinde belirleyici olabilir.
İyi SQL Alışkanlıkları ve Sık Yapılan Hatalar
SQL’de “çalışıyor” olması, “doğru ve sürdürülebilir” olduğu anlamına gelmez. Uzun vadede en büyük kazanım, okunabilir ve ölçülebilir sorgular yazmaktır. Aşağıdaki noktalar, günlük işlerde kaliteyi hızlıca artırır.
SELECT * yerine ihtiyaca yönelik kolon seçimi
SELECT * başlangıçta pratik görünse de büyüyen tablolarda maliyetli hale gelir. Ayrıca şema değişikliklerinde sürpriz sonuçlara yol açabilir. Kolonları açık seçmek; hem daha güvenli hem de daha anlaşılırdır.
Filtreleri netleştirme ve tarih aralıkları
Tarih filtresi, raporların en yaygın ihtiyacıdır. BETWEEN kullanımında sınırların dahil edilme durumunu doğru anlamak gerekir. Tarih-saat alanlarında gün sonu gibi detaylar, beklenmedik sonuçlar doğurabilir. Bu nedenle aralıkları açık tanımlamak iyi bir pratiktir.
NULL davranışını göz ardı etmemek
NULL, “boş string” veya “sıfır” değildir. Karşılaştırmalar ve toplama işlemlerinde farklı davranır. Örneğin NULL = NULL ifadesi genellikle doğru dönmez; NULL kontrolleri için IS NULL kullanılmalıdır. Analiz sorgularında NULL yönetimi sonuçların doğruluğunu doğrudan etkiler.
Öğrenmeyi hızlandırmak için yönlendirme
SQL temellerini sistematik biçimde ilerletmek, rastgele örneklerden daha hızlı sonuç verir. Daha fazla örnek, uygulama odaklı alıştırmalar ve performans bakışı için SQL eğitimi sayfasına göz atabilirsiniz.
SQL, hem geliştiriciler hem de analistler için ortak bir “iş dili”dir. SELECT ve JOIN ile doğru veriyi bulur, index ile hız kazanır, transaction ile güven inşa edersiniz. Bu dört temel, çoğu gerçek dünya senaryosunun omurgasını oluşturur.
Bir sonraki adım olarak, kendi veriniz üzerinde küçük denemeler yapın: Bir raporu hızlandırmak için filtreleri sadeleştirin, sık kullanılan kolonları tespit edip index etkisini ölçün, transaction sınırlarını netleştirin. Böylece SQL, sadece bir sözdizimi değil; karar verme ve problem çözme aracı haline gelir.


