Ders 01 / 18
SQL Dil Aileleri
Tanımlama, işleme, sorgulama, denetim ve işlem deyimleri: hangi ailenin neyi değiştirdiği, bildirimsel yazımın anlamı ve kurs boyunca kullanılacak kütüphane şemasının kurulması.
İçindekiler
Veri Modelleme ve İlişkisel Kuram kursu bir şema bırakarak bitti: bağıntılar, birincil ve yabancı anahtarlar, varlık ve başvuru bütünlüğü kısıtları, normalleştirilmiş tablolar. O kursun ürettiği şey bir tasarımdı — kâğıt üzerinde tutarlı, ama henüz sorulmamış. Bir şemanın değeri, ona sorulabilen sorularla ölçülür.
Bu kurs o soruları soran dili kurar. Dilin adı yapılandırılmış sorgu dili (Structured Query Language, SQL) ve ilişkisel modelin kuramsal işlemlerini — seçme, izdüşüm, birleştirme — yazıya döken standart arayüzdür. İlk ders dilin haritasını çıkarır: hangi deyim ailesi neyi değiştirir, bir deyim nasıl okunur ve kurs boyunca üzerinde çalışılacak veri nasıl kurulur.
Bildirimsel Bir Dil
Programlama Temelleri kursunda yazılan her döngü nasıl sorusunu yanıtlıyordu: diziyi baştan sona gez, koşulu sağlayanı birikece ekle, sonucu döndür. SQL bu soruyu sormaz. SQL ne istendiğini yazar; sonuca hangi sırayla, hangi veri yapısıyla, hangi dizinle ulaşılacağına motor karar verir. Bu yüzden SQL bir bildirimsel dildir (declarative language).
Ayrımın pratik sonucu şudur: aynı soruyu farklı yazımlarla ifade eden iki sorgu, motorun seçtiği sorgu planı (query plan) aynı olduğunda aynı hızda çalışır. Yazımın kendisi başarımı belirlemez; belirleyen, motorun yazımdan çıkardığı plandır. Bu, kursun ilerleyen bölümlerinde tekrar edilecek bir ayrımdır — şimdilik yalnız şu kadarı yeter: SQL’de bir sorguyu iyileştirmek, çoğunlukla döngüyü hızlandırmak değil, soruyu daha kesin sormaktır.
Deyim Aileleri
SQL tek bir dil olarak öğretilir ama içinde birbirinden farklı beş iş yapan deyim kümesi barındırır. Bu kümeler geleneksel olarak şöyle adlandırılır:
| Aile | Açılım | Ne yapar | Örnek deyimler |
|---|---|---|---|
| Tanımlama | veri tanımlama dili (data definition language) | Şemanın kendisini kurar ve değiştirir | CREATE, ALTER, DROP |
| İşleme | veri işleme dili (data manipulation language) | Tablolardaki satırları ekler, değiştirir, siler | INSERT, UPDATE, DELETE |
| Sorgulama | veri sorgulama dili (data query language) | Var olan veriden yeni bir sonuç kümesi üretir | SELECT |
| Denetim | veri denetim dili (data control language) | Nesneler üzerinde yetki verir ve alır | GRANT, REVOKE |
| İşlem | işlem denetim dili (transaction control language) | Bir grup değişikliği bütün olarak kesinleştirir ya da geri alır | COMMIT, ROLLBACK |
Ayrım keyfi değil: her ailenin geri alınabilirliği ve etkilediği şey farklıdır. Sorgulama hiçbir şeyi değiştirmez. İşleme satırları değiştirir ve bir işlem içindeyse geri alınabilir. Tanımlama şemayı değiştirir ve geri alınabilirliği motora göre değişir — bazı motorlar şema değişikliğini işlemin parçası sayar, bazıları tanımlama deyimini gördüğü anda açık işlemi kendiliğinden kesinleştirir.
Bu kursun ilk iki konusu yalnız sorgulamayla ilgilenir; üçüncü konu işleme ve tanımlama deyimlerine geçer. Denetim deyimleri de o konuda ele alınır.
Şemayı Kurmak
Kurs boyunca tek bir örnek sürecek: bir kütüphanenin ödünç kayıtları. Dört tablo var — şubeler, kitaplar, üyeler ve ödünç işlemleri. Bu, İlişkisel Kuram kursunda normalleştirmesi yapılan şemanın aynısıdır.
Aşağıdaki blok bir veritabanı dosyası oluşturur ve dört tabloyu tanımlar. Komut satırında
çağrılan motor sqlite3; dosya adı kutuphane.db. Deyimlerin kendisi standart tanımlama
deyimleridir.
rm -f kutuphane.db sqlite3 kutuphane.db <<'SQL' CREATE TABLE sube ( sube_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT NOT NULL ); CREATE TABLE kitap ( kitap_id INTEGER PRIMARY KEY, baslik TEXT NOT NULL, yazar TEXT NOT NULL, basim_yili INTEGER, sube_id INTEGER REFERENCES sube(sube_id) ); CREATE TABLE uye ( uye_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, soyad TEXT NOT NULL, eposta TEXT, kayit_tarihi TEXT NOT NULL ); CREATE TABLE odunc ( odunc_id INTEGER PRIMARY KEY, kitap_id INTEGER NOT NULL REFERENCES kitap(kitap_id), uye_id INTEGER NOT NULL REFERENCES uye(uye_id), alis_tarihi TEXT NOT NULL, iade_tarihi TEXT ); SQL sqlite3 kutuphane.db '.tables'
kitap odunc sube uye
Tanımlarda İlişkisel Kuram kursundaki üç kavram doğrudan görünüyor. PRIMARY KEY birincil
anahtarı, REFERENCES yabancı anahtarı, NOT NULL ise bir sütunun boş değer kabul
etmediğini bildirir. basim_yili, eposta ve iade_tarihi sütunlarında NOT NULL
yazmaması bilinçlidir: basım yılı bilinmeyen kitap, elektronik posta adresi vermemiş üye
ve henüz iade edilmemiş ödünç kaydı olabilir. Bu üç sütun kursun ilerleyen derslerinde boş
değer davranışını göstermek için kullanılacak.
Veriyi Yerleştirmek
Şema boş bir iskelettir. Aşağıdaki blok, bir önceki blokta oluşturulan kutuphane.db
dosyasına örnek satırları ekler ve tablo başına satır sayısını yazdırır. .headers on ve
.mode column satırları komut satırı aracının çıktı biçimini belirler; sorgunun kendisiyle
ilgileri yoktur.
sqlite3 kutuphane.db <<'SQL' INSERT INTO sube VALUES (1,'Merkez','Ankara'),(2,'Bahçelievler','Ankara'), (3,'Kadıköy','İstanbul'),(4,'Konak','İzmir'); INSERT INTO kitap VALUES (1,'Körlük','José Saramago',1995,1),(2,'Tutunamayanlar','Oğuz Atay',1972,1), (3,'Kum Kitabı','Jorge Luis Borges',1975,2),(4,'Yaban','Yakup Kadri',1932,2), (5,'Sessiz Ev','Orhan Pamuk',1983,3),(6,'Anayurt Oteli','Yusuf Atılgan',NULL,3), (7,'Tehlikeli Oyunlar','Oğuz Atay',1973,NULL); INSERT INTO uye VALUES (1,'Ayşe','Demir','[email protected]','2023-02-14'), (2,'Mehmet','Kaya','[email protected]','2023-05-30'),(3,'Zeynep','Arslan',NULL,'2024-01-09'), (4,'Emre','Yıldız','[email protected]','2024-03-22'),(5,'Selin','Aydın',NULL,'2024-11-05'), (6,'Burak','Şahin','[email protected]','2025-01-18'); INSERT INTO odunc VALUES (1,1,1,'2025-01-10','2025-01-24'),(2,2,1,'2025-02-02','2025-02-20'), (3,1,2,'2025-02-11',NULL),(4,3,3,'2025-03-01','2025-03-15'),(5,4,3,'2025-03-18','2025-04-02'), (6,1,4,'2025-04-05','2025-04-19'),(7,5,4,'2025-04-21',NULL),(8,2,5,'2025-05-02','2025-05-30'), (9,7,1,'2025-05-14','2025-05-28'),(10,3,5,'2025-06-03',NULL),(11,6,2,'2025-06-11','2025-06-25'), (12,4,4,'2025-06-20','2025-07-04'); .headers on .mode column SELECT 'kitap' AS tablo, COUNT(*) AS satir FROM kitap UNION ALL SELECT 'uye', COUNT(*) FROM uye UNION ALL SELECT 'odunc', COUNT(*) FROM odunc; SQL
tablo satir ----- ----- kitap 7 uye 6 odunc 12
Bu iki blok kurs boyunca tekrarlanacak. Her ders kendi başına çalışabilsin diye, izleyen derslerin başında aynı şema ve veri sıkıştırılmış tek bir blok olarak yeniden verilecek.
Bir Sorgunun İskeleti
Üçüncü aile — sorgulama — tek bir deyimden oluşur: SELECT. Kurulan veriye yöneltilen en
kısa soru şöyle görünür.
sqlite3 kutuphane.db <<'SQL' .headers on .mode column SELECT baslik, basim_yili FROM kitap WHERE yazar = 'Oğuz Atay'; SQL
baslik basim_yili ----------------- ---------- Tutunamayanlar 1972 Tehlikeli Oyunlar 1973
Deyim üç yan tümceden (clause) oluşuyor: SELECT hangi sütunların döneceğini,
FROM hangi tablodan okunacağını, WHERE hangi satırların kalacağını söylüyor. Yazım
sırası bu, ama anlam sırası farklıdır — motor önce FROM, sonra WHERE, en son SELECT
yan tümcesini değerlendirir. Bir sonraki ders bu sırayı ayrıntılandırır.
Yazımla ilgili üç kural şimdiden geçerlidir. Anahtar sözcükler büyük/küçük harfe duyarlı değildir; büyük harfle yazılmaları yalnızca okunabilirlik geleneğidir. Metin değerleri tek tırnak içine alınır — çift tırnak standartta tanıtıcı (identifier), yani tablo ve sütun adı, alıntılamak içindir. Her deyim noktalı virgülle biter; bu, birden çok deyimin arka arkaya yazılabilmesini sağlar.
İşlemin Geri Alınabilirliği
İşleme deyimleri şemayı değil satırları değiştirir ve bu değişiklik bir işlem (transaction) içinde geçici tutulabilir. İşlem, ya bütünüyle kesinleşen ya da bütünüyle geri alınan bir deyim öbeğidir.
sqlite3 kutuphane.db <<'SQL' .headers on .mode column BEGIN; DELETE FROM odunc WHERE iade_tarihi IS NULL; SELECT COUNT(*) AS islem_icinde FROM odunc; ROLLBACK; SELECT COUNT(*) AS geri_alindiktan_sonra FROM odunc; SQL
islem_icinde ------------ 9 geri_alindiktan_sonra --------------------- 12
İşlemin içinde tablo dokuz satırlı görünüyor, geri alma sonrasında yeniden on iki satır.
Silinen üç satır hiçbir zaman kalıcı olmadı. COMMIT yazılsaydı sonuç dokuz satırda
sabitlenecekti. İşlemlerin yalıtım düzeyleri ve eşzamanlılık davranışı İleri SQL kursunun
konusudur; burada yalnız şu kadarı gerekli: bir değişikliği denemenin güvenli yolu, onu
BEGIN ile başlayan bir öbeğe koymaktır.
Standart ve Lehçe
SQL bir standarda dayanır, ama hiçbir motor standardı eksiksiz gerçekleştirmez ve her motor standardın üstüne kendi eklerini koyar. Bu eklere lehçe (dialect) denir. Kursta öğretilen kurallar standarda ait olanlardır; bir davranış motora göre değişiyorsa metinde açıkça işaretlenir.
Ayrım pratikte üç yerde karşımıza çıkar. Birincisi, sonuç kümesini sınırlama yazımıdır — standart yazım ile yaygın kısayol farklıdır. İkincisi, örüntü eşlemenin büyük/küçük harf davranışıdır. Üçüncüsü, dış birleştirmenin bazı yönlerinin her motorda bulunmamasıdır. Bu üçü de ilgili derslerinde ayrıca ele alınacak.
Lehçe farkına karşı tutum, taşınabilirliği bir amaç değil bir ölçüt saymaktır: standart yazım varken lehçeye özgü yazımı seçmek, sorguyu belirli bir ürüne bağlar. Bu bazen bilinçli bir karardır; bilinçsiz olduğunda göç maliyeti olarak geri döner.
Özet
- SQL bildirimsel bir dildir: sonucun ne olacağı yazılır, nasıl hesaplanacağına motor karar verir.
- Deyimler beş aileye ayrılır — tanımlama, işleme, sorgulama, denetim ve işlem — ve her ailenin etkilediği şey ile geri alınabilirliği farklıdır.
- Kurs boyunca kullanılacak şema dört tablodan oluşur: şube, kitap, üye ve ödünç işlemi; boş değer kabul eden üç sütun bilinçli olarak bırakılmıştır.
- Bir sorgu yan tümcelerden kurulur ve yazım sırası ile değerlendirme sırası aynı değildir.
- İşleme deyimleri bir işlem içine alınarak denenebilir;
ROLLBACKdeğişikliği hiç olmamış hale getirir. - Standart SQL ile motor lehçesi ayrı şeylerdir; motora bağlı davranışlar bu kursta ayrıca işaretlenir.
Sonraki Adım
Bu derste SELECT yalnızca bir örnek olarak geçti. Oysa sorgulama ailesinin tamamı tek bu
deyimden ibarettir ve gücü, sütun listesinin sabit adlardan çok daha fazlasını kabul
etmesinden gelir: hesaplanmış ifadeler, yeniden adlandırılmış sütunlar, yinelenen satırların
elenmesi. Sonraki ders SELECT yan tümcesinin yapısını ve tablo sütunları ile sorgu
sütunları arasındaki farkı kurar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.