Kapsamlı MySQL Veritabanı Eğitimi (18 Adım)

1.1 Veritabanı (Database) ve RDBMS Kavramları

Veritabanı, verilerin bilgisayar ortamında sistematik, organize ve yapılandırılmış bir şekilde saklandığı elektronik bir depodur. Bu yapı, verilere kolayca erişim, yönetim ve güncelleme imkanı sunar. Günümüz yazılım dünyasının temel taşıdır ve basit bir web sitesinden karmaşık kurumsal sistemlere kadar her yerde kullanılır.

DBMS ve RDBMS Arasındaki Kritik Farklar

DBMS (Database Management System / Veritabanı Yönetim Sistemi), verilerin depolanmasını, alınmasını ve yönetimini sağlayan genel bir yazılım sistemidir. Ancak DBMS'nin en popüler alt kümesi RDBMS'tir.

RDBMS (Relational Database Management System / İlişkisel Veritabanı Yönetim Sistemi), verileri tablolar halinde (satırlar ve sütunlar) depolar ve bu tablolar arasında önceden tanımlanmış ilişkiler kurar. MySQL, PostgreSQL, Oracle ve SQL Server gibi sistemler RDBMS sınıfına girer. İlişkisellik, veri bütünlüğünü sağlamanın ve tekrarı (redundancy) azaltmanın anahtarıdır. İlişkiler, Primary Key ve Foreign Key gibi anahtarlar aracılığıyla kurulur, bu da verilere tutarlılık katar.

MySQL Nedir, Ne İşe Yarar?

MySQL, en popüler açık kaynaklı RDBMS'lerden biridir. Adını "My" (kurucu ortağın kızının adı) ve "SQL" (Structured Query Language) kelimelerinden alır. Özellikle web uygulamaları için bir endüstri standardı haline gelmiştir (LAMP/MAMP/XAMPP yığınlarının "M"si). Yüksek performans, güvenilirlik, esneklik ve geniş bir topluluk desteği sunması, onu küçük projelerden devasa kurumsal çözümlere kadar ideal kılar. SQL dilini kullanarak veritabanına sorgular gönderilir ve veriler işlenir.

İlişkisel Olmayan (Non-Relational / NoSQL) Veritabanları

Veri tabanı türlerinin sadece RDBMS ile sınırlı olmadığını bilmek önemlidir. NoSQL veritabanları (örneğin MongoDB, Redis), esnek şemaları (Schema-less) ve yatay ölçeklenebilirlikleri sayesinde yapılandırılmamış veya yarı yapılandırılmış büyük veri setleri için kullanılır. Ancak, katı veri bütünlüğü gerektiren (örneğin bankacılık işlemleri) uygulamalar için RDBMS (MySQL) hala en doğru seçimdir.

Kusursuz Öğrenme İpucu: Bir veritabanı uzmanı olmanın ilk adımı, veriyi neden tablolar halinde organize ettiğimizi ve tablolar arası ilişkilerin (JOIN'ler, anahtarlar) veri tutarlılığını nasıl sağladığını tam olarak anlamaktır. MySQL'in gücü bu ilişkisel modelde yatar.

1.2 MySQL Mimarisi ve SQL Yapısı

MySQL, İstemci-Sunucu (Client-Server) Mimarisi üzerinde çalışır. Bu mimaride, MySQL sunucusu tüm verileri, tabloları ve işleme mantığını yönetir. İstemci (Client) ise (bir web uygulaması, komut satırı veya MySQL Workbench gibi bir araç), ağ üzerinden sunucuya bağlanır ve SQL sorguları gönderir. Sunucu, sorguyu işler, sonuçları hazırlar ve istemciye geri gönderir.

Depolama Motorları (Storage Engines) Kavramı

MySQL'in en güçlü yanlarından biri, çekirdek mimarisi ile veri depolama katmanını ayıran Depolama Motoru konseptidir. Farklı tablolar için farklı motorlar kullanılabilir, bu da esneklik sağlar.

  • InnoDB (Varsayılan): İşlem (Transaction) desteği, satır seviyesinde kilitleme ve Foreign Key kısıtlamaları sunar. Kritik uygulamalar ve veri bütünlüğü için standarttır.
  • MyISAM (Eski): Daha hızlı salt okuma işlemleri için tasarlanmıştır, ancak işlem ve Foreign Key desteği yoktur. Artık çok tercih edilmez.

SQL (Structured Query Language) Yapısı

SQL, veritabanlarıyla konuşmanın standart dilidir. Sorgular dört ana kategoriye ayrılır:

  • DDL (Data Definition Language): Veritabanı nesnelerinin yapısını tanımlar (CREATE, DROP, ALTER).
  • DML (Data Manipulation Language): Verilerin kendisini yönetir (SELECT, INSERT, UPDATE, DELETE).
  • DCL (Data Control Language): Kullanıcı izinlerini ve yetkilerini yönetir (GRANT, REVOKE).
  • TCL (Transaction Control Language): İşlemleri yönetir (COMMIT, ROLLBACK).

Temel bir SQL sorgusu (SELECT) şu bileşenlerden oluşur:

SELECT sütunlar/ifadeler FROM tablo_adi [JOIN'ler] [WHERE koşulu] [GROUP BY] [HAVING] [ORDER BY] [LIMIT];

Bu sıralama, MySQL'in sorguyu işleme sırasına göre neredeyse sabittir. Sorguların yazılış sırası ile MySQL'in onları işleme sırasının farklı olduğunu bilmek, özellikle performans optimizasyonu (Bölüm 16) için hayati öneme sahiptir.

2.1 MySQL Server, XAMPP/WAMP Kurulumu

MySQL öğrenimine başlamadan önce çalışan bir sunucu ortamına ihtiyacımız vardır. Bu, ya bağımsız bir MySQL Server kurulumu ya da hepsi bir arada paketler (XAMPP/WAMP/MAMP) aracılığıyla sağlanır.

Bağımsız MySQL Server Kurulumu

Resmi MySQL Installer (Windows), APT (Linux) veya Homebrew (macOS) gibi paket yöneticileri kullanılarak yapılabilir. Bu, sadece MySQL sunucusunu kurar ve genellikle daha temiz bir üretim ortamı için tercih edilir. Kurulum sırasında root şifresi ve port (varsayılan 3306) ayarı yapılır.

XAMPP/WAMP/MAMP Paketleri

Bu paketler (Web sunucusu Apache, Veritabanı MySQL, Programlama Dili PHP/Perl), özellikle PHP geliştiricileri için yerel geliştirme ortamını (localhost) hızla kurmayı sağlar. XAMPP (Çapraz Platform) en popüleridir. Kurulumdan sonra XAMPP kontrol panelinden MySQL servisini başlatmak yeterlidir. Bu, aynı zamanda bir web arayüzü yönetim aracı olan phpMyAdmin'i de otomatik olarak kurar.

MySQL Workbench Tanıtımı

MySQL'in resmi masaüstü uygulamasıdır. Veritabanı tasarımından (ER diyagramları), SQL geliştirmeye, sunucu yönetimine ve performans takibine kadar geniş bir yelpazede profesyonel araçlar sunar. phpMyAdmin'den daha güçlüdür ve büyük projelerde tavsiye edilir. Workbench ile bağlantı kurarken genellikle localhost (127.0.0.1) adresi ve root kullanıcı adı kullanılır.

Kusursuz Öğrenme İpucu: Geliştirme sürecinde hem görsel arayüz (Workbench) hem de komut satırı (CLI) kullanmayı öğrenin. En iyi profesyoneller, komut satırını hız ve otomasyon için görsel arayüzü ise karmaşık yapıları incelemek için kullanır.

2.2 Komut Satırı (CLI) ile MySQL Kullanımı ve Temel Komutlar

Komut Satırı Arayüzü (CLI), hızlı yönetim görevleri, yedekleme ve otomasyon için vazgeçilmezdir. MySQL'e bağlanmak için terminal veya komut istemcisinde şu komut kullanılır:

mysql -u [kullanici_adi] -p

-u kullanıcı adını (genellikle root), -p ise şifreyi soracağını belirtir. Bağlantı başarılı olursa MySQL komut istemi belirir (mysql>).

Temel Yönetim Komutları

Veritabanı yapısını incelemek ve bağlamı değiştirmek için bu komutlar kullanılır:

  • SHOW DATABASES;: Sunucudaki tüm veritabanlarını listeler.
  • USE [db_adi];: Çalışılacak aktif veritabanını seçer. Tüm tablo işlemleri bu veritabanı içinde yapılacaktır.
  • SHOW TABLES;: Aktif veritabanındaki tüm tabloları listeler.
  • DESCRIBE [tablo_adi]; veya DESC [tablo_adi];: Tablonun sütun adlarını, veri tiplerini ve kısıtlamalarını gösterir.
  • SELECT VERSION();: MySQL sunucusunun sürümünü gösterir.
  • QUIT; veya \q: Komut satırından çıkar.

Güvenliğe Giriş

İlk kurulumdan sonra root kullanıcısının şifresini değiştirmek ve web uygulamaları için ayrı, kısıtlı yetkilere sahip kullanıcılar oluşturmak temel bir güvenlik adımıdır. Bu, yetkilendirme konusunun (Bölüm 13) temelini oluşturur.

ALTER USER 'root'@'localhost' IDENTIFIED BY 'YeniGucluSifre!';

Bu bölüm, öğrencilerin hem görsel hem de CLI ortamında rahatça çalışabilmesi için bir köprü görevi görür ve profesyonel çalışma alışkanlığını geliştirir.

3.1 CREATE/DROP DATABASE/TABLE İşlemleri

Veritabanı yapısını kurmak, DDL (Data Definition Language) komutlarının ana işidir. Öğrencinin bir sistemi sıfırdan kurabilmesi için bu komutlarda uzmanlaşması gerekir.

Veritabanı Oluşturma ve Yönetimi

Veritabanı oluştururken, karakter setini (Charset) ve sıralama düzenini (Collation) doğru seçmek, özellikle Türkçe karakterler için hayati öneme sahiptir. UTF8MB4 (emoji dahil tüm Unicode karakterleri destekler) ve UTF8MB4_TURKISH_CI (case-insensitive / büyük-küçük harf duyarsız) en çok tavsiye edilen ayarlardır.

CREATE DATABASE proje_yonetimi_db CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci; DROP DATABASE IF EXISTS eski_db;

Veritabanını silmeden önce IF EXISTS kullanmak, zaten silinmiş bir veritabanını silmeye çalışmaktan kaynaklanacak hatayı (error) önler. USE komutundan sonra, artık tüm işlemlerimiz seçili veritabanı bağlamında yürütülür.

Tablo Oluşturma (CREATE TABLE)

Tablolar, verilerin depolandığı temel yapılardır. Tablo oluştururken sadece sütun adlarını değil, veri tiplerini ve kısıtlamaları (constraints) da doğru tanımlamak gerekir.

CREATE TABLE calisanlar ( calisan_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ad VARCHAR(50) NOT NULL, soy_ad VARCHAR(50) NOT NULL, pozisyon ENUM('Yazilimci', 'Tasarimci', 'Yonetici') DEFAULT 'Yazilimci', ise_giris_tarihi DATE );

Bu örnekte INT UNSIGNED ile negatif sayıları engelliyor, AUTO_INCREMENT PRIMARY KEY ile otomatik artan benzersiz bir anahtar belirliyor ve ENUM ile pozisyon değerlerini kısıtlayarak veri bütünlüğünü sağlıyoruz.

3.2 Veri Türleri (INT, VARCHAR, DATE, FLOAT, TEXT) ve Kısıtlamalar

Veri tipi seçimi, hem depolama verimliliği hem de sorgu performansı açısından kritiktir. Yanlış veri tipi seçimi, gereksiz disk alanı israfına veya hatalı veri depolamaya yol açar.

Temel Veri Türleri Kategorileri

  • Sayısal:
    • INT: Tam sayılar. TINYINT, SMALLINT, MEDIUMINT, BIGINT gibi alt tipleri mevcuttur. Mümkün olan en küçük tipi seçmek, performansı artırır.
    • DECIMAL(P, S): Hassas ondalık sayılar (para birimleri için ideal). P toplam hane sayısı, S ondalıktan sonraki hane sayısıdır.
    • FLOAT/DOUBLE: Yaklaşık ondalık sayılar (bilimsel hesaplamalar için uygundur, finansal işlemler için kaçınılmalıdır).
  • Metin (String):
    • VARCHAR(N): Değişken uzunlukta metin. N maksimum karakter sayısını belirtir. Genellikle ad, unvan, e-posta gibi kısa metinler için kullanılır.
    • CHAR(N): Sabit uzunlukta metin. Belirlenen N uzunluğunda değilse boşluklarla doldurulur. Performans için kısaltmalar ve kodlar (örneğin ülke kodları) için idealdir.
    • TEXT: Uzun metinler için (blog yazıları, yorumlar). Daha yavaş işlem görür, indekslenmesi zordur.
  • Tarih ve Zaman:
    • DATE: YYYY-MM-DD formatında tarih.
    • DATETIME: YYYY-MM-DD HH:MM:SS formatında tarih ve zaman.
    • TIMESTAMP: Genellikle kayıt/güncelleme zamanını otomatik tutmak için kullanılır.

Kısıtlamalar (Constraints)

Kısıtlamalar, tablolara kurallar koyarak verilerin geçerliliğini ve bütünlüğünü garantiler:

  • NOT NULL: Bu sütun boş (NULL) olamaz.
  • DEFAULT: Eğer değer belirtilmezse, bu varsayılan değeri kullan.
  • UNIQUE: Sütundaki tüm değerler benzersiz olmalıdır (NULL değerler hariç).
  • PRIMARY KEY: UNIQUE ve NOT NULL kısıtlamalarının birleşimidir.
  • FOREIGN KEY: İlişkileri kurar ve referans bütünlüğünü garanti eder (Bölüm 7).

4.1 INSERT, UPDATE, DELETE İşlemleri (CRUD)

CRUD (Create, Read, Update, Delete), veritabanı yönetiminin temelini oluşturan dört temel işlemdir. Bu bölümde CUD (Create, Update, Delete) komutlarını inceliyoruz.

INSERT INTO (Oluşturma - Create)

Tabloya yeni bir satır (kayıt) eklemek için kullanılır. Sütun adlarını belirtmek iyi bir pratiktir, böylece tablonun yapısı değişse bile sorgu çalışmaya devam eder.

INSERT INTO urunler (urun_adi, fiyat, stok_adet) VALUES ('Akıllı Saat', 4500.00, 25); -- Çoklu kayıt ekleme INSERT INTO personel (ad, soy_ad) VALUES ('Melda', 'Aslan'), ('Ali', 'Demir');

Eğer tüm sütunlara değer giriliyorsa, sütun adlarını belirtme zorunluluğu yoktur, ancak bu önerilmez.

UPDATE (Güncelleme - Update)

Mevcut kayıtların değerlerini değiştirmek için kullanılır. UPDATE, genellikle bir WHERE koşulu ile birlikte kullanılır. WHERE koşulu olmadan çalıştırılırsa, tablonun TÜM kayıtları güncellenir, bu da büyük bir veri kaybına yol açabilir.

UPDATE urunler SET fiyat = 4000.00, stok_adet = 30 -- Güncellenecek sütunlar WHERE urun_adi = 'Akıllı Saat'; -- Hangi kaydın güncelleneceği

DELETE (Silme - Delete)

Tablodan bir veya daha fazla kaydı silmek için kullanılır. Tıpkı UPDATE gibi, WHERE koşulunun dikkatli kullanılması gerekir. DELETE komutu sadece satırları siler, tablonun yapısını silmez.

DELETE FROM personel WHERE pozisyon = 'Stajyer' AND ise_giris_tarihi < '2024-01-01';

Tüm tabloyu hızlıca silmek ve otomatik artan (AUTO_INCREMENT) sayacı sıfırlamak için TRUNCATE TABLE [tablo_adi]; komutu daha etkilidir.

4.2 WHERE Koşulu, Karşılaştırma ve Mantıksal Operatörler

WHERE yan tümcesi, SELECT, UPDATE ve DELETE sorgularının en temel filtreleme mekanizmasıdır. Sorgunun veri kümesini hangi kriterlere göre seçeceğini, güncelleyeceğini veya sileceğini belirler.

Karşılaştırma Operatörleri

İki değeri kıyaslamak için kullanılırlar:

  • = (Eşittir)
  • > (Büyüktür), < (Küçüktür)
  • >= (Büyük Eşittir), <= (Küçük Eşittir)
  • <> veya != (Eşit Değildir)
  • IN (...): Değerin parantez içindeki listede olup olmadığını kontrol eder. (Örn: WHERE kategori_id IN (1, 5, 8))

Mantıksal Operatörler

Birden fazla koşulu birleştirmek için kullanılırlar ve sorgunun karmaşıklığını artırırlar:

  • AND: Tüm koşulların doğru olması gerekir.
  • OR: Koşullardan en az birinin doğru olması yeterlidir.
  • NOT: Koşulun tersini alır.

Özel Filtreleme İfadeleri

  • LIKE: Metin tabanlı aramalarda desen eşleştirme için kullanılır. % (sıfır veya daha fazla karakter) ve _ (tek bir karakter) joker karakterlerdir. SELECT ad FROM musteriler WHERE ad LIKE 'M%da'; (M ile başlayıp da ile biten)
  • BETWEEN: İki değer aralığını kontrol eder (dahil). WHERE fiyat BETWEEN 100 AND 500;
  • NULL Değerlerle Çalışma: NULL, bilinen bir değer olmadığı anlamına gelir (sıfır veya boş dize değildir). NULL değerleri kontrol etmek için sadece IS NULL veya IS NOT NULL kullanılır. Eşittir (=) operatörü NULL ile çalışmaz.
Kusursuz Öğrenme İpucu: Mantıksal operatörler kullanılırken parantezleri `()` doğru kullanmak, sorgunun öncelik sırasını doğru belirler ve istenmeyen sonuçları engeller. Örneğin: `WHERE kategori = 'A' AND (fiyat > 500 OR stok < 10);`

5.1 ORDER BY, LIMIT ve DISTINCT

Bu yan tümceler, SELECT sorgularının sonuç kümesini biçimlendirmek ve sunmak için kullanılır, verilerin sunum kalitesini artırır.

ORDER BY (Sıralama)

Sonuç kümesini bir veya birden fazla sütuna göre sıralamak için kullanılır. Varsayılan sıralama ASC (Ascending / Artan) şeklindedir. DESC (Descending / Azalan) ile ters sıralama yapılır.

Birden fazla sütunla sıralama yaparken, öncelik sırası soldan sağa doğrudur. Önce ilk sütuna göre sıralanır, aynı değere sahip kayıtlar varsa ikinci sütuna göre sıralanır:

SELECT ad, soyad, maas FROM personel ORDER BY maas DESC, soyad ASC;

Bu sorgu, önce maaşı en yüksekten en düşüğe sıralar, maaşları aynı olanları ise soyadlarına göre alfabetik (A'dan Z'ye) sıralar.

LIMIT (Sınırlama)

Sonuç kümesindeki satır sayısını sınırlandırır. Özellikle sayfalama (pagination) işlemlerinde ve en çok/en az N kaydı bulma sorgularında kritiktir.

-- İlk 10 kaydı getir SELECT * FROM urunler LIMIT 10; -- 2. sayfayı getir (10 kaydı atla, sonraki 10 kaydı al) SELECT * FROM urunler LIMIT 10 OFFSET 10;

Bu yapı, `LIMIT [offset], [count]` şeklinde de yazılabilir. Örneğin, `LIMIT 10, 10`.

DISTINCT (Benzersiz Değerler)

SELECT ifadesinde belirtilen sütunlardaki yinelenen (duplicate) değerleri kaldırarak yalnızca benzersiz değerleri listeler.

-- Sadece benzersiz şehir isimlerini listeler SELECT DISTINCT sehir FROM musteriler; -- Birden fazla sütun için: Sadece benzersiz (sehir, ulke) çiftlerini listeler SELECT DISTINCT sehir, ulke FROM musteriler;

5.2 Hesaplama (Aggregate) Fonksiyonları

Hesaplama fonksiyonları (Aggregate Functions), bir sütun üzerindeki değerlerin tamamı üzerinde işlem yapar ve tek bir sonuç değeri döndürür. Bu fonksiyonlar genellikle GROUP BY yan tümcesiyle (Bölüm 9) birlikte kullanılarak her grup için bir hesaplama sonucu üretir.

Ana Hesaplama Fonksiyonları

  • COUNT(\*): Tablodaki toplam satır sayısını döndürür.
  • COUNT([sutun]): Belirtilen sütunda NULL olmayan değerlerin sayısını döndürür.
  • SUM([sutun]): Sayısal bir sütundaki değerlerin toplamını döndürür.
  • AVG([sutun]): Sayısal bir sütundaki değerlerin aritmetik ortalamasını döndürür.
  • MAX([sutun]): Sütundaki en büyük değeri döndürür.
  • MIN([sutun]): Sütundaki en küçük değeri döndürür.

Örnek Kullanım ve ALIAS (Takma Ad)

Hesaplama sonucu dönen sütuna ALIAS (AS) ile anlamlı bir isim vermek, çıktıyı daha okunaklı hale getirir.

SELECT COUNT(DISTINCT musteri_id) AS ToplamBenzersizMusteri, AVG(fiyat) AS OrtalamaUrunFiyati FROM siparisler;

COUNT fonksiyonu içine DISTINCT ifadesini ekleyerek, sadece benzersiz müşteri ID'lerinin sayısını almış oluruz. Bu, tekrarlanan sipariş veren müşterilerin tek bir kez sayılmasını sağlar.

Hesaplama fonksiyonları, veritabanı performansının önemli bir parçasıdır, çünkü büyük veri setlerinde bu hesaplamaları sunucunun yapması, uygulama katmanının (PHP, Python) iş yükünü azaltır.

6.1 Metin, Sayısal ve Tarih Fonksiyonları

Fonksiyonlar, veritabanında saklanan ham veriyi manipüle etmek ve dönüştürmek için kullanılan güçlü araçlardır. Uygulama tarafında yapmak yerine veritabanı katmanında yapmak, genellikle daha performanslıdır.

Metin (String) Fonksiyonları

Metin verilerini biçimlendirme ve işleme amaçlıdır:

  • CONCAT(s1, s2, ...): Birden fazla dizeyi birleştirir. SELECT CONCAT(ad, ' ', soyad) AS tam_ad FROM personel;
  • LENGTH(s): Dizinin uzunluğunu byte cinsinden döndürür.
  • CHAR_LENGTH(s): Dizinin karakter sayısını döndürür (Türkçe karakterlerde önemlidir).
  • UPPER(s) / LOWER(s): Metni büyük harfe / küçük harfe dönüştürür.
  • SUBSTRING(s, başlangıç, uzunluk): Dizinin bir bölümünü döndürür.
  • TRIM(s): Baş ve sondaki boşlukları kaldırır.

Sayısal Fonksiyonlar

Sayısal değerler üzerinde matematiksel işlemler yapar:

  • ROUND(x, d): x sayısını d ondalık basamağa yuvarlar.
  • ABS(x): Mutlak değeri döndürür.
  • MOD(x, y): x'in y'ye bölümünden kalanı (modülo) döndürür.
  • CEIL(x) / FLOOR(x): Sayıyı yukarı / aşağı yuvarlar.

Tarih ve Zaman Fonksiyonları

Tarih ve zaman değerlerini elde eder, biçimlendirir ve karşılaştırır:

  • NOW(): Mevcut tarih ve zamanı döndürür (DATETIME).
  • CURDATE() / CURTIME(): Sadece mevcut tarihi / zamanı döndürür.
  • DATE_FORMAT(tarih, format): Tarihi istenen formata dönüştürür (Örn: '%Y-%m-%d').
  • DATEDIFF(d1, d2): İki tarih arasındaki gün farkını hesaplar.
  • YEAR(tarih) / MONTH(tarih) / DAY(tarih): Tarihin ilgili bileşenini çeker.

6.2 IF ve CASE WHEN Koşullu İfadeler

SQL'de koşullu ifadeler, verileri sorgu içinde mantıksal kurallara göre dönüştürmeye olanak tanır. Bu, uygulamanın kod karmaşıklığını azaltır ve raporlama sorgularında esneklik sağlar.

IF Fonksiyonu (Basit Koşul)

IF, üç argüman alır: `IF(koşul, doğru_sonuç, yanlış_sonuç)`. Eğer koşul doğruysa ilk sonucu, yanlışsa ikinci sonucu döndürür. Basit ikili (binary) kararlar için idealdir.

SELECT urun_adi, stok_adet, IF(stok_adet > 20, 'Stok Yeterli', 'Stok Azaldi - Siparis Ver!') AS Uyari_Durumu FROM urunler;

CASE WHEN İfadesi (Çoklu Koşul)

CASE WHEN, birden fazla koşulu kontrol etmek ve her koşula karşılık gelen bir değer döndürmek için kullanılır. Birden çok `IF/ELSE IF/ELSE` yapısına eşdeğerdir ve karmaşık iş mantığını SQL'e taşımak için vazgeçilmezdir.

SELECT ad, maas, CASE WHEN maas >= 100000 THEN 'Üst Düzey' WHEN maas >= 50000 THEN 'Orta Düzey' ELSE 'Temel Düzey' END AS Maas_Kategorisi FROM personel;

CASE ifadesi, koşulların sırasına göre değerlendirilir ve ilk doğru koşul bulunduğunda durur. En sona yazılan ELSE ifadesi, hiçbir koşulun sağlanmaması durumunda atanacak varsayılan değeri belirler.

Kusursuz Öğrenme İpucu: CASE WHEN, pivot tablolarda veya raporlama sorgularında veriyi dinamik olarak sınıflandırmak için çok güçlü bir araçtır. Ayrıca `ORDER BY` ifadesinde kullanarak özel sıralamalar da oluşturulabilir.

7.1 Anahtar Kavramları: Primary Key, Foreign Key, Unique Key

Veritabanı anahtarları, veri bütünlüğünü ve tablolar arası ilişkileri sağlamanın temelidir. Anahtarlar, RDBMS'in tutarlı ve güvenilir olmasının garantörüdür.

Primary Key (Birincil Anahtar)

Tablodaki her bir satırı benzersiz bir şekilde tanımlayan sütundur (veya sütun grubudur). İki temel kuralı vardır:

  1. UNIQUE: Asla tekrarlanamaz.
  2. NOT NULL: Asla boş bırakılamaz.

Genellikle AUTO_INCREMENT (otomatik artan) özelliği ile birlikte kullanılır. Bu, uygulamanın ID üretme yükünü veritabanına bırakır.

CREATE TABLE Kategoriler ( kategori_id INT NOT NULL AUTO_INCREMENT, kategori_adi VARCHAR(100) NOT NULL, PRIMARY KEY (kategori_id) );

Foreign Key (Yabancı Anahtar)

Bir tablodaki sütun (veya sütunlar), başka bir tablonun Primary Key'ine referans verdiğinde Foreign Key olur. Bu, tablolar arasındaki bağlantıyı (ilişkiyi) kurar ve Referans Bütünlüğünü (Referential Integrity) sağlar. Örneğin, bir siparişin var olması için veritabanında ilgili bir müşterinin var olması gerekir.

Unique Key (Benzersiz Anahtar)

Sütundaki tüm değerlerin benzersiz olmasını zorunlu kılar, ancak Primary Key'den farklı olarak birden fazla UNIQUE Key tanımlanabilir ve NULL değer almasına izin verilebilir (eğer NOT NULL kısıtlaması eklenmezse). E-posta adresi, TC kimlik numarası gibi benzersiz olması gereken ancak tablonun birincil anahtarı olmayan alanlar için idealdir.

Anahtarların doğru tanımlanması, tablolar arası JOIN işlemlerinin (Bölüm 8) hızlı ve doğru çalışması için de kritik öneme sahiptir.

7.2 İlişki Tipleri (One-to-One, One-to-Many, Many-to-Many) ve Kısıtlamalar

Veritabanı tasarımında, tabloların birbirleriyle nasıl etkileşime girdiğini belirleyen üç temel ilişki tipi vardır.

İlişki Tipleri

  • One-to-One (Birebir): Bir A tablosundaki bir kayıt, B tablosundaki yalnızca bir kayda karşılık gelir (ve tersi). Nadir kullanılır. Örneğin, Personel tablosu ile PersonelDetay tablosu.
  • One-to-Many (Bireçok): Bir A tablosundaki bir kayıt, B tablosundaki birden çok kayda karşılık gelebilir. Bu, en yaygın ilişkidir. Örneğin, bir Kategori'nin birden çok Ürünü olabilir. (Foreign Key, "Many" tarafında bulunur).
  • Many-to-Many (Çokaçok): Bir A tablosundaki bir kayıt, B tablosundaki birden çok kayda, ve B tablosundaki bir kayıt, A tablosundaki birden çok kayda karşılık gelebilir. Bu ilişki, araya bir ara tablo (pivot table) koyularak çözülür.

Referans Bütünlüğü Kısıtlamaları (Foreign Key Actions)

Foreign Key tanımlarken, ana tablodaki bir kayıt silindiğinde veya güncellendiğinde ilişkili tablolarda ne olacağını belirleyen eylemler tanımlanır. Bu kısıtlamalar, veri tutarlılığını garantiler:

  • ON DELETE CASCADE: Ana kaydın silinmesi durumunda, ilişkili tablodaki tüm bağlı kayıtları da siler. (Örn: Müşteri silinirse, o müşteriye ait tüm Siparişler silinsin).
  • ON UPDATE CASCADE: Ana kaydın Primary Key değeri güncellenirse, ilişkili tablodaki Foreign Key değerlerini de otomatik olarak günceller.
  • ON DELETE RESTRICT/NO ACTION: Ana kaydın silinmesine, ilişkili kayıtlar olduğu sürece izin vermez. (Veri kaybını önlemenin en güvenli yoludur).
  • ON DELETE SET NULL: Ana kayıt silinirse, ilişkili tablodaki Foreign Key değerini NULL yapar (eğer sütun NULL alabiliyorsa).

8.1 INNER, LEFT, RIGHT JOIN

JOIN komutları, İlişkisel Veritabanı Yönetim Sistemlerinin (RDBMS) bel kemiğidir. İki veya daha fazla tablodan, aralarındaki ortak sütun (genellikle Foreign Key) üzerinden veri çekerek mantıksal bir sonuç kümesi oluşturur.

INNER JOIN (İç Birleştirme)

Sadece her iki tabloda da eşleşen kayıtları getirir. Ortak bir değer olmayan satırlar sonuç kümesine dahil edilmez. Bu, en sık kullanılan ve en performanslı JOIN türüdür.

-- Sadece sipariş vermiş müşterileri getirir SELECT M.ad, S.siparis_no FROM Musteriler M INNER JOIN Siparisler S ON M.musteri_id = S.musteri_id;

LEFT JOIN (Sol Birleştirme)

Sol tablodaki (FROM'dan sonra gelen) tüm kayıtları getirir. Sağ tabloda eşleşme varsa ilgili sütunları getirir, eşleşme yoksa sağ tablonun sütunları için NULL değer döndürür.

Bu, sol taraftaki kayıtlardan, sağ tarafta karşılığı olmayanları (örneğin hiç sipariş vermemiş müşterileri) bulmak için idealdir.

-- Tüm müşterileri getir, siparişi olanların sipariş numarasını göster, olmayanların NULL göster SELECT M.ad, S.siparis_no FROM Musteriler M LEFT JOIN Siparisler S ON M.musteri_id = S.musteri_id;

RIGHT JOIN (Sağ Birleştirme)

LEFT JOIN'in tam tersidir. Sağ tablodaki tüm kayıtları getirir, sol tablodan eşleşenleri getirir, eşleşme yoksa sol tablonun sütunları için NULL döndürür. Çoğu geliştirici karmaşıklığı önlemek için RIGHT JOIN yerine tablo sırasını değiştirerek LEFT JOIN kullanmayı tercih eder.

Kusursuz Öğrenme İpucu: JOIN işlemlerinde tablo adlarına ALIAS (takma ad, örneğimizde M ve S) vermek, sorgu karmaşıklığını ve yazım hatalarını azaltır.

8.2 FULL JOIN (UNION Alternatifi) ve Alt Sorgular (Subquery)

MySQL, standart bir FULL OUTER JOIN komutuna sahip değildir. Bu sonuç kümesini elde etmek için LEFT JOIN ve RIGHT JOIN sonuçlarını UNION operatörü ile birleştirmek gerekir.

FULL JOIN Simülasyonu

FULL JOIN, her iki tablonun da tüm kayıtlarını getirir. Eşleşmeyen kayıtlar için diğer tablonun sütunları NULL olur.

SELECT * FROM TabloA A LEFT JOIN TabloB B ON A.id = B.id UNION SELECT * FROM TabloA A RIGHT JOIN TabloB B ON A.id = B.id WHERE A.id IS NULL;

Alt Sorgular (Subquery)

Alt sorgu (veya iç sorgu), başka bir SQL sorgusu içinde yer alan sorgudur. Alt sorgular, mantıksal olarak karmaşık filtreleme veya veri hesaplama işlemlerinde kullanılır.

Alt sorgular, sorgunun `SELECT`, `FROM`, `WHERE` ve `HAVING` yan tümcelerinde kullanılabilir:

  • WHERE Yan Tümcesi: Filtreleme için kullanılır. SELECT * FROM urunler WHERE fiyat > (SELECT AVG(fiyat) FROM urunler); (Fiyatı ortalamanın üzerinde olanları getir.)
  • FROM Yan Tümcesi (Türetilmiş Tablo): Bir sorgunun sonucunu geçici bir tablo (Derived Table) olarak kullanır. Bu alt sorgu, bir ALIAS ile adlandırılmalıdır. SELECT T.kategori, T.ortalama FROM (SELECT kategori, AVG(fiyat) AS ortalama FROM urunler GROUP BY kategori) AS T WHERE T.ortalama > 500;

Alt sorgular güçlüdür ancak dikkatli kullanılmazsa sorgu performansını ciddi şekilde düşürebilir. Mümkünse JOIN kullanmak genellikle daha performanslıdır.

9.1 Gruplama (GROUP BY) ve Gruplarda Koşul (HAVING)

Gruplama, bir veritabanı uzmanının en çok kullandığı raporlama aracıdır. GROUP BY yan tümcesi, aynı değere sahip satırları tek bir özet satırında birleştirir. Bu, aggregate (hesaplama) fonksiyonlarının (COUNT, SUM, AVG) her bir grup için ayrı ayrı çalışmasını sağlar.

GROUP BY Kullanımı

Sorgudaki `SELECT` listesinde yer alan, ancak bir aggregate fonksiyonu içinde bulunmayan tüm sütunlar, `GROUP BY` yan tümcesinde de listelenmelidir. Aksi takdirde MySQL hata verir (veya eski MySQL sürümlerinde öngörülemez sonuçlar üretir).

-- Her kategori için kaç adet ürün olduğunu sayar SELECT kategori, COUNT(urun_id) AS urun_sayisi FROM urunler GROUP BY kategori;

HAVING (Gruplanmış Sonuçları Filtreleme)

Veriyi filtrelemek için bildiğimiz WHERE yan tümcesi, gruplama öncesinde çalışır. HAVING yan tümcesi ise gruplama sonrasında çalışır ve sadece gruplanmış sonuçlar üzerinde koşul uygular.

-- Sadece 5'ten fazla ürüne sahip kategorileri raporla SELECT kategori, COUNT(urun_id) AS urun_sayisi FROM urunler GROUP BY kategori HAVING COUNT(urun_id) > 5 ORDER BY urun_sayisi DESC;

Bu sorguda, önce ürünler kategorilere göre gruplandı, sonra grup büyüklüğü 5'ten büyük olan gruplar filtrelendi ve sonuç azalan sırayla sunuldu. Bu, gruplama ve HAVING kullanımının klasik bir örneğidir.

9.2 Gruplarla İstatistiksel Analiz ve TOP N Sorguları

Veritabanı, sadece veri depolamakla kalmaz, aynı zamanda iş zekası (Business Intelligence) ve istatistiksel analiz için de temel platformdur. GROUP BY ve aggregate fonksiyonlarının kombinasyonu, karmaşık analizlere olanak tanır.

Gruplarla İstatistiksel Analiz Örnekleri

  • Aylık Ortalama Satış: Tarih fonksiyonları (YEAR, MONTH) ile gruplama yaparak aylık veya yıllık trendleri analiz edebiliriz. SELECT YEAR(tarih), MONTH(tarih), AVG(tutar) FROM satislar GROUP BY 1, 2;
  • Varyans ve Standart Sapma: MySQL, `VARIANCE()` ve `STDDEV()` gibi yerleşik istatistiksel fonksiyonları sunar. Bunlar, bir veri setindeki yayılımı (dağılımı) ölçmek için kritik öneme sahiptir.
  • En Çok Satış Yapan Müşteri: GROUP BY ile müşterileri gruplayıp, SUM(tutar) ile toplam satış hacmini hesaplamak ve ORDER BY ile sıralamak klasik bir analizdir.

TOP N Sorguları

En yüksek değere sahip ilk N kaydı bulma sorgularına TOP N denir. MySQL'de bu, `ORDER BY` ve `LIMIT` yan tümceleri ile çok basitçe yapılır.

-- En yüksek fiyata sahip 3 ürünü bul SELECT urun_adi, fiyat FROM urunler ORDER BY fiyat DESC LIMIT 3;

Bu yöntem, web sitelerinde "En Çok Satanlar" veya "En Son Eklenenler" gibi listeleri oluşturmanın temelidir. Özellikle `LIMIT` kullanırken performansın kritik olduğunu unutmayın, çünkü sıralama (ORDER BY) işlemi maliyetli olabilir. İndeksler (Bölüm 12) burada devreye girer.

10.1 Veritabanı Normalizasyonu (1NF, 2NF, 3NF)

Normalizasyon, veritabanı tasarımında veri tekrarını (redundancy) en aza indirmek ve veri bütünlüğünü maksimize etmek için uygulanan sistematik bir süreçtir. Normalizasyon, büyük ölçekli ve kritik uygulamalar için vazgeçilmez bir disiplindir.

Normal Formlar (NF)

Normalizasyon, giderek artan gereksinimlere sahip formlara ayrılır. Üçüncü Normal Form (3NF), çoğu ticari uygulama için kabul edilen standarttır.

  • 1NF (Birinci Normal Form): Bir tablonun 1NF'de olması için;
    • Her hücrede tek bir değer olmalı (atomik değerler).
    • Tekrarlayan gruplar olmamalı.
    • Her satır benzersiz olmalı (Primary Key olmalı).
    (Örn: Bir hücrede birden fazla telefon numarası tutmamalısınız.)
  • 2NF (İkinci Normal Form): 1NF şartlarını sağlamalı ve tüm Primary Key olmayan sütunlar, Primary Key'in tamamına bağımlı olmalıdır.
  • 3NF (Üçüncü Normal Form): 2NF şartlarını sağlamalı ve Primary Key olmayan sütunlar arasında geçişli bağımlılık (transitive dependency) olmamalıdır. Yani, A -> B ve B -> C ise, C, A'ya değil B'ye bağlı olmalıdır.

3NF Örneği

Bir `urunler` tablosunda `kategori_id` ile birlikte `kategori_adi` sütununu tutmak, kategori adı değiştiğinde tüm ürünlerdeki bu bilginin güncellenmesini gerektiren bir geçişli bağımlılıktır. 3NF gereği, `kategori_adi` ayrı bir `Kategoriler` tablosunda tutulmalı ve `urunler` tablosu sadece `kategori_id` (Foreign Key) içermelidir. Bu, veri tekrarını önler.

10.2 Varlık-İlişki Diyagramı (ERD) ve İlişkisel Model Tasarımı

Veritabanı tasarımının soyut ve görsel modelleme aşamasıdır. Kod yazmaya başlamadan önce ERD çizmek, tüm varlıkları, nitelikleri ve aralarındaki ilişkileri netleştirdiği için proje hatalarını en aza indirir.

ER Diyagramı (ERD) Bileşenleri

ERD'ler, üç ana bileşenden oluşur:

  • Varlık (Entity): Gerçek dünyadaki nesneler (Müşteri, Ürün, Sipariş). ERD'de dikdörtgen ile gösterilir.
  • Nitelik (Attribute): Varlığın özellikleri (Müşterinin adı, adresi). ERD'de oval ile gösterilir. Primary Key altı çizilerek belirtilir.
  • İlişki (Relationship): Varlıkların birbirleriyle olan bağlantısı (Müşteri - Sipariş Verir). ERD'de eşkenar dörtgen ile gösterilir ve ilişki tipi (1:M, M:N) belirtilir.

İlişkisel Model Tasarımı Örnekleri

ERD çizimi tamamlandıktan sonra, bu görsel model, mantıksal olarak tablolara dönüştürülür. Dönüşüm kuralları:

  1. Her Varlık, bir Tabloya dönüşür.
  2. Her Nitelik, bir Sütuna dönüşür.
  3. One-to-Many ilişkilerde, "Many" tarafındaki tabloya, "One" tarafının Primary Key'i Foreign Key olarak eklenir.
  4. Many-to-Many ilişkilerde, araya yeni bir ara tablo (junction table) oluşturulur. Bu ara tablo, her iki ana tablonun Primary Key'lerini Foreign Key olarak içerir.

Bu sistematik tasarım süreci, normalizasyon kurallarını uygulamayı kolaylaştırır ve sonuç olarak daha tutarlı, ölçeklenebilir bir veritabanı şeması ortaya çıkarır.

11.1 Görünümler (Views) ve Yönetimi

View (Görünüm), bir veya daha fazla tablodan türetilen, ancak fiziksel olarak veri depolamayan, sanal bir tablodur. View, temelinde saklanan bir SELECT sorgusudur ve her çağrıldığında bu sorgu çalıştırılır.

CREATE VIEW (Görünüm Oluşturma)

Görünümler, karmaşık sorguları basitleştirmek, sık kullanılan veriye kolay erişim sağlamak ve güvenlik katmanı oluşturmak için çok değerlidir.

-- 10.000 TL'den fazla maaş alan personelin sadece ad ve pozisyonunu gösteren görünüm CREATE VIEW yuksek_maasli_personel AS SELECT ad, pozisyon, maas FROM personel WHERE maas > 10000; -- Artık bu görünümü sanki bir tabloymuş gibi sorgulayabiliriz: SELECT ad, pozisyon FROM yuksek_maasli_personel;

Görünümlerle Güvenlik

View'lar, kullanıcının temel tabloya doğrudan erişmesini engellerken, sadece belirli sütunları görmesine izin vererek (bu örnekte, maaş bilgisini gizleyebiliriz) veri güvenliğini artırır.

ALTER ve DROP VIEW

Bir görünümün temel sorgusunu değiştirmek için `ALTER VIEW` kullanılır.

ALTER VIEW yuksek_maasli_personel AS SELECT ad, pozisyon, maas, ise_giris_tarihi FROM personel WHERE maas >= 15000; DROP VIEW IF EXISTS yuksek_maasli_personel;

Görünüm Üzerinden Güncelleme

Bazı durumlarda (tek bir tabloya dayanan ve aggregate fonksiyonları içermeyen basit view'lar), görünüm üzerinden `INSERT`, `UPDATE` ve `DELETE` işlemleri yapılabilir. Ancak bu nadirdir ve karmaşık görünümlerde genellikle mümkün değildir. Bu durumda, görünüm sadece okuma amaçlı bir araç olarak kalmalıdır.

12.1 İndeksler (Indexes), Türleri ve CREATE INDEX

İndeks, veritabanı performansının temel anahtarıdır. Tıpkı bir kitabın arkasındaki dizin gibi, veritabanının arama operasyonlarını hızlandırmak için kullanılan özel veri yapılarıdır. İndeksler olmadan, MySQL bir sorguyu yanıtlamak için tablonun tamamını (Full Table Scan) taramak zorunda kalır.

İndeksin Çalışma Mantığı ve Maliyeti

İndeksler, genellikle B-Tree (Balanced Tree) yapısında organize edilir. Bu yapı, veri kümesi ne kadar büyük olursa olsun, çok hızlı bir şekilde (logaritmik zamanda) veri bulmayı sağlar. Ancak, her indeks, diskte yer kaplar ve bir tabloya `INSERT`, `UPDATE` veya `DELETE` işlemi yapıldığında, MySQL'in indeksi de güncellemesi gerekir. Bu nedenle, çok fazla indeks eklemek, yazma (write) performansını düşürebilir. Kural: Yalnızca sıkça sorgulanan sütunlara indeks ekleyin.

İndeks Türleri

  • Primary Index: Primary Key kısıtlaması tanımlandığında otomatik olarak oluşturulur. Tablodaki satırları fiziksel olarak sıraladığı için en hızlı indekstir (InnoDB motorunda).
  • Unique Index: UNIQUE kısıtlaması olan sütunlara otomatik olarak oluşturulur. Veri tekrarını engeller.
  • Standard Index: `WHERE` ve `ORDER BY` yan tümcelerinde sıkça kullanılan sütunlar için manuel olarak oluşturulur.
  • Full-Text Index: Metin sütunlarında (TEXT, VARCHAR) karmaşık metin aramalarını (anahtar kelime arama) hızlandırmak için kullanılır.

İndeks Oluşturma Komutları

İndeksler, tablo oluşturulurken veya sonradan `ALTER TABLE` veya `CREATE INDEX` komutuyla eklenebilir.

-- Sıkça arama yapılan 'email' sütununa benzersiz indeks ekle CREATE UNIQUE INDEX idx_musteri_email ON musteriler (email); -- Sıkça sıralama yapılan 'kayit_tarihi' sütununa normal indeks ekle CREATE INDEX idx_kayit_tarihi ON personel (kayit_tarihi); -- İndeksi silme DROP INDEX idx_musteri_email ON musteriler;

İndekslerin performans üzerindeki etkisini anlamak için EXPLAIN (Bölüm 16) komutunu kullanmak kritik öneme sahiptir.

13.1 Kullanıcı Yönetimi, Yetkilendirme (GRANT) ve Güvenlik

Güvenlik, bir veritabanı yöneticisinin (DBA) en önemli görevidir. Uygulamalar ve farklı geliştiriciler için ayrı kullanıcı hesapları oluşturmak, "en az ayrıcalık ilkesini" (Principle of Least Privilege) uygulamak demektir. Bu, bir güvenlik ihlali durumunda hasarı en aza indirir.

Kullanıcı Oluşturma

Kullanıcı adı ve kullanıcının bağlanabileceği ana makine (host) ile birlikte yeni bir kullanıcı tanımlanır. Güvenli şifreleme algoritması (caching_sha2_password) kullanılmalıdır.

-- Sadece localhost'tan bağlanabilen, uygulamalar için bir kullanıcı oluştur CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'GucluAppSifresi123!'; -- Tüm ana makinelerden (%) bağlanabilen bir analist kullanıcı oluştur CREATE USER 'analist'@'%' IDENTIFIED BY 'RaporSifresi';

Yetki Verme (GRANT)

Kullanıcıya belirli veritabanları, tablolar veya işlemler üzerinde yetki vermek için kullanılır. Yetki seviyeleri: Global (tüm sunucu), Veritabanı, Tablo, Sütun.

-- app_user'a proje_db veritabanındaki tüm tablolar üzerinde SELECT, INSERT, UPDATE, DELETE yetkisi ver GRANT SELECT, INSERT, UPDATE, DELETE ON proje_db.* TO 'app_user'@'localhost'; -- analist'e sadece SELECT yetkisi ver (Sadece okuma, değişiklik yapamaz) GRANT SELECT ON proje_db.* TO 'analist'@'%'; -- Tüm yetkileri uygula FLUSH PRIVILEGES;

Yetki Geri Alma (REVOKE)

Önceden verilmiş yetkileri kaldırmak için kullanılır.

REVOKE DELETE ON proje_db.urunler FROM 'app_user'@'localhost';

Asla, üretim ortamında web uygulaması veya genel kullanıcılar için `root` hesabını kullanmayın. Her zaman kısıtlı yetkilere sahip kullanıcılar tanımlayın.

14.1 Veritabanı Yedekleme ve Geri Yükleme (mysqldump)

Veritabanı yedekleme, felaket kurtarma planının (disaster recovery) en kritik adımıdır. Veri kaybı (donanım arızası, yazılım hatası, kötü amaçlı silme) durumunda sistemi hızlıca geri yüklemek için gereklidir.

mysqldump Aracı

mysqldump, MySQL ile birlikte gelen, veritabanını SQL ifadeleri olarak içeren metin dosyaları halinde yedeklemeye yarayan komut satırı aracıdır. Bu, hem tablo yapısını (CREATE TABLE) hem de veriyi (INSERT INTO) içerir.

Yedekleme Komutları (Komut Satırında)

Sunucunun çalışma zamanı dışından (terminal veya SSH) çalıştırılır.

-- Tek bir veritabanını yedekleme mysqldump -u [kullanici_adi] -p [db_adi] > yedek_dosyasi.sql -- Tüm veritabanlarını yedekleme mysqldump -u [kullanici_adi] -p --all-databases > tum_veriler.sql -- Sadece tablo yapısını yedekleme (veri olmadan) mysqldump -u [kullanici_adi] -p [db_adi] --no-data > yapi_yedek.sql

Geri Yükleme Komutları (Komut Satırında)

Yedeklenen SQL dosyasını bir veritabanına geri yüklemek için `mysql` komutu kullanılır.

-- Veritabanının önce oluşturulması gerekir: CREATE DATABASE yeni_db; mysql -u [kullanici_adi] -p yeni_db < yedek_dosyasi.sql

Büyük veritabanlarında yedekleme/geri yükleme için `InnoDB` motorunda Transaction özelliğini korumak ve `LOCK-TABLES` gibi ek parametreler kullanmak önemlidir. Ayrıca, yedeklerin mutlaka ayrı bir sunucuda veya bulut depolama alanında tutulması gerekir (3-2-1 kuralı).

15.1 Gelişmiş Konular: Trigger (Tetikleyiciler) ve Stored Procedure (Saklı Yordamlar)

Gelişmiş veritabanı uzmanları, iş mantığının bir kısmını uygulama katmanından alıp doğrudan veritabanı sunucusuna taşımak için bu nesneleri kullanır. Bu, performansı artırır ve veri bütünlüğünü garantiler.

Trigger (Tetikleyiciler)

Trigger, bir tabloda belirli bir olay (INSERT, UPDATE, DELETE) meydana geldiğinde otomatik olarak çalışan bir SQL kod bloğudur. Otomatik denetim, günlükleme (logging) ve karmaşık kısıtlamalar uygulamak için idealdir.

  • Zamanlama: `BEFORE` (Olaydan önce) veya `AFTER` (Olaydan sonra).
  • Olay: `INSERT`, `UPDATE`, `DELETE`.
-- Bir sipariş her eklendiğinde, ilgili ürünün stok miktarını azaltan trigger CREATE TRIGGER stok_azaltma AFTER INSERT ON siparis_detay FOR EACH ROW BEGIN UPDATE urunler SET stok_adet = stok_adet - NEW.miktar WHERE urun_id = NEW.urun_id; END;

Stored Procedure (Saklı Yordamlar)

Saklı yordamlar, önceden derlenmiş ve sunucuda depolanmış SQL kod bloklarıdır. Uygulama katmanından tek bir çağrı ile karmaşık bir dizi SQL işlemini çalıştırabilirler. Avantajları: Performans (tekrar derlenmez), Güvenlik (kullanıcıların sadece prosedürü çalıştırmasına izin verilebilir), Basitleştirme.

-- Tek bir müşterinin siparişlerini getiren prosedür DELIMITER // CREATE PROCEDURE MusteriSiparisleriniGetir (IN musteri_id INT) BEGIN SELECT * FROM siparisler WHERE musteri_id = musteri_id; END // DELIMITER ;

15.2 Transaction Yönetimi (COMMIT, ROLLBACK) ve Event Scheduler

Transaction'lar ve Event Scheduler, veritabanı güvenilirliği ve otomasyonu için temel unsurlardır. InnoDB depolama motoru Transaction'ları desteklerken, MyISAM desteklemez.

Transaction (İşlem) Yönetimi

Transaction, veritabanı işlemlerinin bir dizi adım olarak algılandığı ve bu adımların ya hep birlikte başarılı olması (COMMIT) ya da hiçbirinin olmaması (ROLLBACK) gerektiği bir mekanizmadır. Bu, bankacılık işlemlerinde (bir hesaptan para çıkışı ve diğerine girişi) kritik öneme sahiptir.

Transaction'ların dört temel özelliği (ACID) vardır:

  • Atomicity (Bölünmezlik): Ya hepsi ya hiçbiri.
  • Consistency (Tutarlılık): İşlem sonunda veritabanı geçerli bir durumda kalmalıdır.
  • Isolation (İzolasyon): Aynı anda çalışan işlemler birbirini etkilememelidir.
  • Durability (Kalıcılık): Taahhüt edilen (committed) veriler kalıcı olmalıdır.
START TRANSACTION; UPDATE hesaplar SET bakiye = bakiye - 100 WHERE id = 1; UPDATE hesaplar SET bakiye = bakiye + 100 WHERE id = 2; -- Eğer her iki güncelleme de başarılıysa: COMMIT; -- Eğer ikinci güncelleme başarısız olursa: ROLLBACK;

Event Scheduler (Zamanlanmış Görevler)

MySQL sunucusu içinde, belirli zamanlarda veya düzenli aralıklarla otomatik olarak SQL komutları çalıştırmak için kullanılır. Örnek: Gece yarısı eski kayıtları temizleme, günlük raporları hesaplama.

SET GLOBAL event_scheduler = ON; CREATE EVENT eski_kayitlari_temizle ON SCHEDULE EVERY 1 DAY STARTS '2025-10-28 03:00:00' DO DELETE FROM log_tablosu WHERE tarih < DATE_SUB(CURDATE(), INTERVAL 30 DAY);

16.1 Performans ve Optimizasyon: Sorgu Optimizasyonu (EXPLAIN)

Veritabanı optimizasyonu, uygulamanın hızını ve ölçeklenebilirliğini doğrudan etkileyen en ileri seviye konudur. Bir sorgu yavaş çalıştığında, problemin nerede olduğunu anlamak için EXPLAIN komutu kullanılır.

EXPLAIN Komutu ve Çıktı Analizi

EXPLAIN, MySQL'in bir sorguyu nasıl çalıştırmayı planladığını gösteren yürütme planını (execution plan) döndürür. Bu plan, optimizasyon için hayati ipuçları içerir.

EXPLAIN SELECT * FROM urunler WHERE kategori_id = 5 AND fiyat > 1000;

EXPLAIN çıktısında bakılması gereken kritik alanlar:

  • type: Sorgunun ne kadar verimli olduğunu gösterir. `const`, `eq_ref`, `ref` en iyi tiplerdir. `ALL` (Full Table Scan / tüm tabloyu tarama) en kötü tiptir ve indeks eksikliğine işaret eder.
  • rows: MySQL'in tahmini olarak kaç satır tarayacağını gösterir. Bu sayı ne kadar düşükse o kadar iyidir.
  • key: Hangi indeksin kullanıldığını gösterir. `NULL` ise indeks kullanılmıyor demektir.
  • Extra: Ek bilgi alanıdır. `Using filesort` (sıralama için geçici tablo oluşturuldu, maliyetli), `Using temporary` (gruplama için geçici tablo oluşturuldu, maliyetli) ifadelerinden kaçınılmalıdır.

Yaygın Optimizasyon Teknikleri

  1. İndeks İyileştirmesi: Sık kullanılan WHERE ve JOIN sütunlarına indeks eklemek (`type: ALL` sorununu çözer).
  2. Sorgu Yapısının İyileştirilmesi: `SELECT *` yerine sadece gerekli sütunları seçmek. `LIKE '%deger'` gibi indeks kullanamayan ifadelerden kaçınmak.
  3. Normalization: Veri tekrarını azaltmak, daha az ve daha küçük JOIN'ler gerektirir.

17.1 MySQL ve Programlama Dilleri Entegrasyonu: PHP (PDO) ve Python Bağlantıları

Veritabanı, arka plan (backend) uygulamalarıyla konuşmak zorundadır. Bu iletişim için her dilin kendi sürücüleri ve kütüphaneleri vardır. Modern ve güvenli entegrasyon için Prepared Statements (Hazırlanmış İfadeler) kullanmak mutlak zorunluluktur.

PHP ile PDO (PHP Data Objects)

PDO, PHP'de veritabanı bağlantısı için tercih edilen yöntemdir. Farklı veritabanları için tutarlı bir arayüz sağlar ve en önemlisi, SQL Enjeksiyonu saldırılarına karşı koruma sağlayan hazırlanmış ifadeleri destekler.

PDO ile Güvenli Veri Çekme (Prepared Statement):

<?php // 1. Bağlantı Kurulumu $pdo = new PDO("mysql:host=localhost;dbname=proje_db;charset=utf8mb4", 'app_user', 'password'); // 2. Hazırlanmış İfade (Sorgu ve Veriyi Ayırma) $kullanici_id = $_GET['id']; // Kullanıcıdan gelen veri $stmt = $pdo->prepare('SELECT ad, email FROM musteriler WHERE id = ?'); $stmt->execute([$kullanici_id]); // Veriyi ayrı gönder $kullanici = $stmt->fetch(PDO::FETCH_ASSOC); if ($kullanici) { echo "Kullanıcı Adı: " . $kullanici['ad']; } ?>

PDO, veriyi sorgudan ayırdığı için (veriyi tırnak içine almaz, sadece değer olarak iletir), kötü amaçlı kodların çalışmasını engeller.

Python ile Bağlantı (mysql.connector)

Python'da popüler olan kütüphane `mysql.connector`'dur. Temel mantık, PDO ile aynıdır: önce bağlantı kurulur, sonra sorgular cursor nesnesi aracılığıyla yürütülür.

Python Örneği:

import mysql.connector # Bağlantı Kurulumu mydb = mysql.connector.connect( host="localhost", user="app_user", password="password", database="proje_db" ) # Prepared Statement ile Sorgu Çalıştırma cursor = mydb.cursor() musteri_id = 42 sql = "SELECT ad, email FROM musteriler WHERE id = %s" cursor.execute(sql, (musteri_id,)) result = cursor.fetchone() print(result) cursor.close() mydb.close()

18.1 Uygulama Projeleri (Öğrenci Kayıt Sistemi, E-Ticaret Veritabanı)

Teorik bilgi, ancak pratik projelerle pekiştiğinde kalıcı hale gelir. MySQL'i kusursuz öğrenmenin son adımı, tüm bilgileri bir araya getiren gerçek dünya senaryolarını uygulamaktır. Aşağıdaki projeler, tüm müfredatı kapsamaktadır.

Proje 1: Öğrenci Kayıt Sistemi (Bireçok İlişki)

  • Tablolar: Öğrenci, Bölüm, Notlar.
  • İlişki: Bir Bölüm'ün birden çok Öğrencisi, bir Öğrencinin birden çok Notu olabilir (One-to-Many).
  • Uygulanan Konular: Tablo tasarımı (3NF), Foreign Key kısıtlamaları, Öğrenci ortalamasını hesaplamak için `AVG()` ve `GROUP BY` kullanımı.
  • Zorluk: Öğrencinin sadece kendi bölümündeki dersleri seçebilmesini sağlayan karmaşık kısıtlamaların tasarlanması.

Proje 2: E-Ticaret Ürün ve Sipariş Veritabanı (Çokaçok İlişki)

  • Tablolar: Müşteri, Ürün, Sipariş, Sipariş Detay (Ara Tablo).
  • İlişki: Bir Siparişin birden çok Ürünü, bir Ürünün birden çok Siparişi olabilir (Many-to-Many).
  • Uygulanan Konular: `JOIN` işlemleri, `TRIGGER` (Stok güncelleme), `TRANSACTION` (Sipariş oluşturma sırasında atomiklik).
  • Zorluk: Ürün fiyatlarının geçmişe dönük takibi ve raporlanması.

Proje 3: Kitaplık Yönetim Sistemi (Kullanıcı Yönetimi)

  • Tablolar: Kitap, Yazar, Üye, Kiralama.
  • Uygulanan Konular: `VIEW` (Sadece ödünç alınan kitapları gösteren görünüm), `USER` ve `GRANT` komutları (Kütüphaneci ve Üye rolleri için farklı yetkiler tanımlama), Tarih fonksiyonları (`DATEDIFF` ile geciken kiralamaların tespiti).
  • Zorluk: İndeks optimizasyonu (Hızlı yazar ve kitap arama), Geciken kiralamalar için otomatik bildirim (Event Scheduler).

Bu projelerin tamamını bitiren bir öğrenci, MySQL'i sadece kullanmakla kalmaz, aynı zamanda profesyonel düzeyde tasarlayabilir ve yönetebilir hale gelir.