Bence, SQL’e yeni girenlerin büyük çoğunluğu ilk gün şu iki şeyi karıştırıyor: tabloyu kurmak ile tablonun içine veri koymak. Açık konuşayım — ben de yıllar önce bir staj projesinde PostgreSQL’i ilk açtığımda bu ayrımı kafamda tam oturtamamıştım. Bir komut çalışıyor, tablo oluşuyor; öteki çalışıyor, satır ekleniyor… ama hangisi neyi değiştiriyor, işin aslı biraz bulanıktı. Hani “tamam bir şeyler oldu” diyorsun ama tam olarak ne olduğunu sorsan cevap veremiyorsun.
İşte tam burada DDL ve DML devreye giriyor. Biri veritabanının iskeletini kuruyor, diğeri o iskeletin içine et koyuyor, hareket veriyor (evet, doğru duydunuz). Şöyle söyleyeyim: DDL evin duvarlarıysa DML içindeki mobilya, eşya ve yaşayan hayat gibi düşünebilirsiniz. Kaba bir benzetme, biliyorum — ama işe yarıyor.
Bunu yaşayan biri olarak söyleyeyim, Bu yazıda konuyu ezber cümlelerle değil, sahada nasıl göründüğüyle anlatacağım. Küçük bir startup’ta işler hızlı akar ya; tabloyu iki dakikada açarsın, sonra üç farklı ekip aynı veriyi kurcalar. Kurumsal tarafta ise her ALTER öncesi toplantı bile olabilir. İkisi arasında ciddi bir uçurum var — bunu da göreceğiz.
DDL ve DML Neyi Yönetiyor?
İnanın, DDL, yani Data Definition Language, veritabanının yapısını tanımlayan komutları kapsıyor. Tablo oluşturmak, kolon eklemek, tablo silmek ya da bir alanın tipini değiştirmek gibi işler burada dönüyor. Yani veriyle değil, verinin yaşayacağı kabukla uğraşıyor — bu ayrım önemli.
Peki neden?
Şunu söyleyeyim, DML ise Data Manipulation Language tarafı. Burada amaç tabloyu ayakta tutmak değil; tablonun içindeki kayıtları eklemek, güncellemek veya silmek. Başka bir deyişle çatı tamam mı diye bakmıyor, evde kim oturuyor, adres doğru mu, telefon numarası güncel mi — ona odaklanıyor.
Bir de işin pratik tarafı var. Çoğu yeni başlayan “SQL öğrendim” deyince aslında sadece SELECT yazmayı öğrenmiş oluyor. Halbuki SELECT tek başına sizi veri okuyan biri yapar; sistem tasarlayan biri yapmaz. Tasarım tarafında DDL’yi bilmeden yürümek giderek zorlaşır — özellikle tablo sayısı arttıkça.
Kafadaki en net ayrım
Şöyle düşünün: DDL = yapı, DML = içerik. Bu kadar net aslında. Ama günlük projelerde bu ikisi çok (söylemesi ayıp) karışıyor (bizzat test ettim). Bazen aynı anda kullanıyorsunuz; önce CREATE atıp hemen ardından INSERT basıyorsunuz. Neden önemli bu? O yüzden ayrımı teoride değil, pratikte oturtmak lazım.
Bakın, burayı atlarsanız yazının kalanı anlamsız kalır.
| Kategori | Amaç | Örnek Komutlar | Etki Alanı |
|---|---|---|---|
| DDL | Veritabanı yapısını tanımlamak | CREATE, ALTER, DROP, TRUNCATE | Tablo / şema / kolon yapısı |
| DML | Tablodaki veriyi yönetmek | INSERT, UPDATE, DELETE | Kayıtlar / satırlar |
CREATE ile Temeli Atmak
Bana göre SQL öğrenirken ilk ciddi önemli adım CREATE TABLE komutudur. Neden mi? Çünkü burada artık “veri okumuyorum” hissi değil, doğrudan sistem tasarlıyorum hissi geliyor — ikisi çok farklı şeyler. Geçen yıl Şubat ayında İstanbul’da bir e-ticaret paneli için mini bir raporlama modülü hazırlarken bunu yeniden yaşadım; önce tabloyu doğru kurmadığınızda sonraki her şey yamuk gidiyor, üstüne bir de düzeltmeye çalıştıkça daha da karışıyor (bizzat test ettim)
Aşağıdaki örneğe bakalım:
CREATE TABLE IF NOT EXISTS students (
student_id INT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
gender CHAR(1),
date_of_birth DATE,
class VARCHAR(10),
city VARCHAR(50)
);
Şahsen, Bu örnekte öğrenci bilgileri için gayet temiz bir başlangıç var. Primary key her satırı tekilleştiriyor; yani öğrenci kimliği tekrar edemiyor. NOT NULL ise boş geçilmesin demek. Basit görünüyor — ama veri kalitesinin bel kemiği tam da burada yatıyor, başka yerde değil.
Neyse uzatmayalım: iyi tasarlanmamış tablo sonradan dert çıkarır. Mesela isimleri tek kolonda tutarsınız da soyadı aramada saç baş yoldurur. Ya da tarih alanını metin olarak saklarsınız ve raporlamada patlarsınız, anlayacağınız. Kağıt üstünde küçük hata gibi görünür ama pratikte can sıkar — hem de uzun süre sıkar.
Küçük startup ile büyük kurum aynı şeyi yaşamaz
Küçük startup’ta genelde hız baskın olur. “Şimdilik aç gitsin” denir ve şema biraz aceleye gelir. Bu yaklaşım erken aşamada iş görebilir ama büyüdükçe teknik borç diye geri döner — kaçınılmaz olarak.
Şimdi, kurumsal tarafta ise CREATE bile kontrollüdür; migration dosyası hazırlanır, test ortamında denenir, bazen iki kere denenir, sonra canlıya alınır. Benzer bir akışı 2023’te Ankara’daki bir SaaS projesinde gördüm — sadece yeni kolon eklemek için bile release notu hazırlanmıştı. İlk duyduğumda “bu kadar da olmaz” dedim ama sonra mantığını anladım.
ALTER ile Yapıyı Sonradan Düzenlemek
ALTER komutu bence SQL’in en gerçekçi taraflarından biri, çünkü hayatta hiçbir sistem ilk haliyle mükemmel kalmıyor. Kullanıcı ister değiştirir, ürün yöneticisi yeni alan ister, iş kuralı kayar falan derken şema da şekil değiştirir — bu kaçınılmaz bir süreç.
`ALTER TABLE`, mevcut tabloda kolon ekleme, silme, yeniden adlandırma gibi işleri yapıyor:
ALTER TABLE students
ADD phone_number VARCHAR(20);
ALTER TABLE subjects
RENAME COLUMN credits TO credit_hours;
ALTER TABLE students
DROP COLUMN phone_number;
Bi saniye — Burası güzel ama biraz da tehlikeli bölge. Mesela production ortamında kolon silmek öyle kafaya göre yapılmaz! Bir defasında Mart 2024’te İzmir’de çalışan bir arkadaşım yanlışlıkla kullanılmayan sandığı kolonu kaldırdı; meğer raporlama servisi onu arka planda okuyormuş… iki saatlik minik panik yaşandı. Sonunda çözüldü ama o iki saat uzun geçmişti.
Nerede dikkat etmek lazım?
- Add column: Genelde güvenli başlar ama default değeri düşünmeniz gerekir.
- Drop column: En riskli hareketlerden biri; bağımlılık kontrolü şarttır. (bu kritik)
- Rename column: Işık hızıyla sorun çıkarabilir çünkü uygulama kodu eski adı bekliyor olabilir.
- Add constraint: Zaten bozuk veriniz varsa işlem hata verebilir.
Şunu açık söyleyeyim: ALTER komutu kulağa masum geliyor ama canlı sistemde en çok hata çıkaran hamlelerden biri olabiliyor. Bilhassa de migration sırası bozuksa ya da uygulama kodu eski şemaya bağlıysa işler çabuk karışır. Kısacası “küçük değişiklik” diye geçmeyin.
DML Tarafında Veriyle Dans Etmek
Şunu açık söyleyeyim: ALTER komutu kulağa masum geliyor ama canlı sistemde en çok hata çıkaran hamlelerden biri olabiliyor. Bilhassa de migration sırası bozuksa ya da uygulama kodu eski şemaya bağlıysa işler çabuk karışır. Kısacası “küçük değişiklik” diye geçmeyin.
DML kısmına gelince işler daha tanıdık hale geliyor. Artık masada satırlar var; kullanıcı kayıtları var, siparişler var, loglar var… Yani gerçek hayatın kendisi orada duruyor diyebiliriz.
Bakın, burayı atlarsanız yazının kalanı anlamsız kalır.
`INSERT`, tabloya yeni kayıt ekler: Daha fazla bilgi için İki Chrome Eklentisiyle Dikkat ve Güven Savaşı yazımıza bakabilirsiniz.
INSERT INTO students (
student_id,
first_name,
last_name,
gender,
date_of_birth,
class,
city
)
VALUES
(1,'Amina','Wanjiku','F','2008-03-12','Form 3','Nairobi'),
(2,'Brian','Ochieng','M','2007-07-25','Form 4','Mombasa'),
(3,'Cynthia','Mutua','F','2008-11-05','Form 3','Kisumu');
Bunu ilk gördüğünüzde “tamam ya bu kolay” diyorsunuz genelde. Sonra tek satırlık INSERT yerine binlerce satır yükleme gelince olay değişiyor tabii! Batch insert mi kullanacaksınız? Transaction gerekecek mi? Hata olursa geri alma planınız var mı? İşte orası önemli — ve orası artık başka bir yazının konusu. Bu konuyla ilgili iPhone 18 Pro’da Renk Oyunu: Bordo Sızıntısı Ne Diyor? yazımıza da göz atmanızı tavsiye ederim.
İlginç olan şu ki, `UPDATE`, mevcut kaydı değiştirir; mesela öğrencinin şehir bilgisini düzeltirsiniz ya da telefon numarasını yenilersiniz.
`DELETE`, kaydı siler — fakat dürüst olayım, ben prod ortamda fiziksel DELETE yerine çoğu zaman soft delete tercih edilmesini daha sağlıklı buluyorum, özellikle denetim gereken sistemlerde.
Sessiz ama kritik farklar
Hemen hissedilmeyen şeyler sonradan baş ağrıtır.
INSERT veri ekler. UPDATE veri düzeltir. DELETE ise işi kökten çözer… bazen fazla kökten. Küçük detay gibi duruyor ama operasyon tarafında bambaşka sonuçları var. Bu konuyla ilgili Apple Çin’de Neden Tökezliyor? Watch Satışlarındaki Sert Düşüş yazımıza da göz atmanızı tavsiye ederim. Volkanik Kaya Çimentosu: Betonun Karbon Yükü Azalıyor yazımızda da bu konuya değinmiştik. Hava Bahsi Büyüyor: Tahmin Piyasaları Gerçeği Okuyor mu? yazımızda da bu konuya değinmiştik.
Bir de şu var: eğer yanlışlıkla WHERE koymadan UPDATE atarsanız tüm tablo gider. Evet. Gerçekten hepsi.
Ben bunu ilk kez Şubat ayında kendi test ortamımda yaşadığımda ekranın karşısında birkaç saniye donup kaldığımı hatırlıyorum — neyse ki canlı değildi, yoksa çok farklı bir hikaye olurdu. O yüzden SQL’de refleks haline gelmesi gereken alışkanlık şu: önce SELECT ile hedefi doğrula, sonra UPDATE veya DELETE uygula. Bu kadar basit, bu kadar önemli.
Dikkat Edilmezse Küçük Hata Büyük Soruna Döner
DDL ve DML arasındaki fark teoride basit görünür ama pratikte sınırlar bazen bulanıklaşıyor. Mesela schema migration sırasında (belki yanılıyorum ama) hem ALTER hem INSERT birlikte gelir. Ya da raporlama için oluşturduğunuz geçici tablolar kısa sürede production mantığına dönüşür — farkında bile olmadan.
Ben editör masasında bu konuyu incelerken özellikle yeni başlayanların en çok yaptığı hatanın “komutu ezberleyip bağlamı kaçırmak” olduğunu düşünüyorum. Komutun adını bilmek yetmiyor; hangi ortamda çalıştığını, geri dönüş planının olup olmadığını. Hangi servislerin o tabloya bağlı olduğunu da düşünmeniz gerekiyor. Bunlar sorulmadan yazılan komutlar zamanla sorun üretiyor.
Bence, Bakın şimdi küçük tabloda durum daha rahat anlaşılır:
| Senaryo | Doğru Yaklasim | Risk |
|---|---|---|
| Yeni özellik için tablo açma | CREATE + index planlama | Düşük |
| Mevcut kolona alan ekleme | ALTER + test + migration | Orta |
| Eski kayıtları topluca düzeltme | UPDATE + transaction | Orta |
| Gereksiz veriyi silme | DELETE yerine archive stratejisi | Yüksek |
Bir startup’ta hızlı karar vermek avantajdır. Ama enterprise seviyede hızdan çok izlenebilirlik önem kazanıyor. Log yoksa geçmiş yoktur — geçmiş yoksa sorun çözmek zorlaşır. Basit ama görmezden gelinen bir gerçek bu.
Ha bu arada, uzun vadede iyi SQL bilen ekiplerin farkı tam burada ortaya çıkıyor: yalnızca komut yazmazlar, verinin yaşam döngüsünü düşünürler. İşte profesyonellik biraz böyle bir şey.
Sahadan Küçük Tavsiyeler ve Pratik Alışkanlıklar
İşin teorisini geçtim — günlük kullanımda birkaç alışkanlık hayat kurtarıyor. Mesela ben her zaman önce staging ortamında denerim; özellikle DROP veya büyük UPDATE öncesinde bunu otomatiğe bağlamak iyi fikir olur. Bir başka alışkanlık da yedek almadan canlıya dokunmamak — klişe gibi duruyor ama hâlâ birçok ekip bunu es geçiyor.
- Mümkünse her şema değişikliğini versiyonlayın.
- Büyük update işlemlerini parça parça çalıştırın.
WHEREfiltresini iki kere kontrol edin.- Tabloyu silecekseniz bağımlılık zincirini muhtemelen inceleyin.
- Migration sonrası uygulama loglarını hemen takip edin.
Bakın şimdi en önemli nokta şu: SQL öğrenirken yalnızca sözdizimine takılırsanız yüzeyde kalırsınız. Ama niyetini anlarsanız — yani hangi komut neyi temsil ediyor bilirseniz — veri modelleme kısmında bayağı yol alırsınız (ben de ilk duyduğumda şaşırmıştım)
Daha önce açık kaynaklı bir proje üzerinde çalışırken buna birebir denk geldim; topluluk içinde herkes INSERT biliyordu fakat kimse neden ayrı audit tablosu tutulduğunu sorgulamıyordu. Sonra büyüyen veri seti yüzünden ana tabloda performans düştü ve çözüm yine düzgün tasarıma çıktı. Yani mesele hep aynı yere bağlanıyor: ilk temeli düzgün atmak.
İşte tam da bu noktada devreye giriyor.
Sıkça Sorulan Sorular
DDL ile DML arasındaki temel fark nedir?
DDL veritabanının yapısını yönetir; CREATE ve ALTER gibi komutlarla tabloyu şekillendirir. DML ise tablodaki veriyi yönetir; INSERT, UPDATE ve DELETE bunun içindedir.
Create table hangi kategoriye girer?
[ERROR]
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



