Yükleniyor...

MySQL Best Practices: 10 Adımda Kapsamlı Optimizasyon [2026 Rehberi]

Yazar: Burak Balkı | Kategori: Database | Okuma Süresi: 35 dk

2026 yılına özel MySQL best practices rehberimizle veritabanı performansınızı ve güvenliğinizi en üst düzeye çıkarın. Kurulumdan ileri seviye optimizasyona k...

# MySQL Best Practices: 10 Adımda Kapsamlı Optimizasyon [2026 Rehberi] ### BÖLÜM 1 - Giriş Paragrafı (Hook + Context) Veritabanı performansı, modern uygulamaların en kritik başarı faktörlerinden biridir. Yavaş sorgular veya güvensiz yapılandırmalar, kullanıcı deneyimini olumsuz etkilemekle kalmaz, aynı zamanda sistemin genel kararlılığını da tehlikeye atar. Bu kapsamlı **MySQL best practices** rehberinde, 2026 yılı itibarıyla en güncel ve etkili yöntemleri inceleyerek veritabanı mimarinizi nasıl optimize edeceğinizi, güvenliğini nasıl sağlayacağınızı ve performansını nasıl artıracağınızı öğreneceksiniz. Amacımız, projelerinizde karşılaşabileceğiniz yaygın sorunlara karşı sizi donatarak, daha ölçeklenebilir ve dayanıklı sistemler kurmanıza yardımcı olmaktır. ### BÖLÜM 2 - MySQL Nedir? ## MySQL Nedir? MySQL, açık kaynaklı, ilişkisel bir veritabanı yönetim sistemidir (RDBMS). 2026 itibarıyla küresel çapta en yaygın kullanılan veritabanlarından biri olup, özellikle web uygulamaları ve dinamik içerik yönetim sistemleri (CMS) için tercih edilir. SQL (Structured Query Language) kullanarak verileri yönetir, depolar ve sorgular. Yüksek performans, güvenilirlik ve kullanım kolaylığı sunar. MySQL, Oracle Corporation tarafından geliştirilmekte ve desteklenmektedir. Geniş bir topluluğa sahip olması, kapsamlı dokümantasyonu ve çeşitli programlama dilleriyle entegrasyonu sayesinde geliştiriciler için vazgeçilmez bir araç haline gelmiştir. LAMP (Linux, Apache, MySQL, PHP/Python/Perl) ve MERN (MongoDB, Express.js, React, Node.js) gibi popüler teknoloji yığınlarının bir parçası olarak, küçük ölçekli projelerden kurumsal düzeydeki uygulamalara kadar geniş bir yelpazede kullanılmaktadır. ### BÖLÜM 3 - Neden MySQL Kullanmalısınız? MySQL, geliştiricilere ve kuruluşlara bir dizi somut fayda sunar. Öncelikle, açık kaynaklı olması maliyet avantajı sağlarken, geniş topluluk desteği sayesinde karşılaşılan sorunlara hızlı çözümler bulunabilir. Yüksek performanslı sorgu işleme yeteneği, özellikle okuma ağırlıklı uygulamalarda verimlilik sağlar. Örneğin, bir e-ticaret platformunda binlerce ürün sorgusunu saniyeler içinde işleyebilir. MySQL, veri güvenliği, ölçeklenebilirlik ve esneklik açısından da güçlüdür. Transaction (işlem) desteği, veri bütünlüğünü korurken, replikasyon ve sharding gibi mekanizmalarla yatay ölçeklenebilirlik imkanı sunar. Kurumsal düzeyde destek seçenekleri (Oracle tarafından sağlanan) ise büyük ölçekli projeler için ek güvence sağlar. Peki, kimler için uygundur? Dinamik web siteleri, CMS sistemleri (WordPress, Joomla), e-ticaret platformları, iş zekası uygulamaları ve mobil arka uç servisleri için idealdir. Ancak, yüksek derecede karmaşık ilişkisel modellemeler veya ekstrem yazma yükleri olan dağıtık sistemler için alternatifler değerlendirilmelidir. ### BÖLÜM 4 - MySQL vs Alternatifler (Karşılaştırma Tablosu) Veritabanı seçimi, projenin gereksinimlerine göre büyük ölçüde değişir. MySQL'in yanı sıra PostgreSQL ve MongoDB gibi popüler alternatifler de mevcuttur. Her birinin kendine özgü güçlü ve zayıf yönleri vardır. Aşağıdaki tablo, bu üç popüler veritabanının temel özelliklerini karşılaştırmaktadır. | Özellik | MySQL (8.x) | PostgreSQL (16.x) | MongoDB (7.x) | | :---------------- | :---------------------------------------------- | :------------------------------------------------ | :------------------------------------------------- | | **Tipi** | İlişkisel (RDBMS) | İlişkisel (RDBMS) | Doküman Tabanlı (NoSQL) | | **Veri Modeli** | Tablolar, Satırlar, Sütunlar | Tablolar, Satırlar, Sütunlar (JSONB, XML desteği) | JSON benzeri dokümanlar | | **Performans** | Okuma ağırlıklı iş yüklerinde çok hızlı | Karmaşık sorgularda ve yazma işlemlerinde güçlü | Büyük veri ve yüksek yazma hızlarında başarılı | | **Öğrenme Eğrisi**| Orta, geniş kaynak ve topluluk desteği | Orta-Yüksek, daha fazla özellik | Düşük, esnek şema yapısı | | **Ekosistem** | Çok geniş, LAMP/MERN yığınlarında popüler | Geniş, özellikle veri analizi ve GIS'te popüler | Geniş, gerçek zamanlı ve mobil uygulamalarda popüler | | **Topluluk** | Çok aktif ve büyük | Aktif ve büyüyen | Çok aktif ve büyük | | **Kurumsal Destek**| Oracle tarafından sağlanır | PostgreSQL Global Development Group, ticari firmalar | MongoDB Inc. tarafından sağlanır | | **Kullanım Alanı**| Web uygulamaları, CMS, e-ticaret, bloglar | Kurumsal uygulamalar, BI, GIS, veri ambarları | Büyük veri, IoT, mobil, içerik yönetim sistemleri | Bu karşılaştırma, MySQL'in özellikle web tabanlı, standart ilişkisel veri modeline uygun projelerde ne kadar güçlü olduğunu gösterir. PostgreSQL daha gelişmiş SQL özellikleri ve veri tipleri sunarken, MongoDB esnek şema yapısıyla hızlı prototipleme ve büyük hacimli, yapısal olmayan veriler için öne çıkar. Projenizin özel ihtiyaçlarını dikkatlice analiz ederek en uygun seçimi yapmalısınız. ### BÖLÜM 5 - Kurulum ve İlk Adımlar (Getting Started) MySQL 8.x'in kurulumu, işletim sisteminize göre farklılık gösterse de, temel adımlar genellikle benzerdir. Bu bölümde Ubuntu 22.04 üzerinde kurulumu ve ilk yapılandırma adımlarını anlatacağız. Diğer işletim sistemleri için resmi MySQL dokümantasyonuna başvurmanız önerilir. #### Ön Gereksinimler: * Ubuntu 22.04 veya üzeri bir Linux dağıtımı. * `sudo` yetkilerine sahip bir kullanıcı. * İnternet bağlantısı. #### Adım 1: MySQL Sunucusunu Kurma Terminalinizi açın ve aşağıdaki komutları çalıştırın: ```bash sudo apt update sudo apt install mysql-server -y ``` Bu komutlar sisteminizdeki paket listesini güncelleyecek ve MySQL sunucusunu kuracaktır. #### Adım 2: Güvenlik Yapılandırması Kurulumdan sonra, MySQL'in temel güvenlik ayarlarını yapmak önemlidir. `mysql_secure_installation` script'i bu konuda size yardımcı olacaktır: ```bash sudo mysql_secure_installation ``` Bu script size root parolası belirleme, anonim kullanıcıları kaldırma, uzaktan root girişini devre dışı bırakma ve test veritabanını kaldırma gibi seçenekler sunacaktır. Güvenli bir kurulum için tüm sorulara `Y` (Evet) yanıtı vermeniz önerilir. #### Adım 3: MySQL Servisini Kontrol Etme MySQL servisinin çalışır durumda olduğundan emin olmak için aşağıdaki komutu kullanabilirsiniz: ```bash sudo systemctl status mysql ``` Çıktıda `active (running)` ifadesini görmelisiniz. Eğer çalışmıyorsa, `sudo systemctl start mysql` komutuyla başlatabilirsiniz. #### Adım 4: MySQL'e Bağlanma Kurulum tamamlandıktan sonra, root kullanıcısı olarak MySQL kabuğuna bağlanabilirsiniz: ```bash sudo mysql -u root -p ``` Kurulum sırasında belirlediğiniz root parolasını girmeniz istenecektir. Başarılı bir şekilde giriş yaptığınızda MySQL komut istemcisini (`mysql>`) göreceksiniz. Artık veritabanı oluşturmaya ve yönetmeye hazırsınız! ```sql -- Yeni bir veritabanı oluşturma CREATE DATABASE my_app_db; -- Kullanıcı oluşturma ve yetkilendirme CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'GucluParola2026!'; GRANT ALL PRIVILEGES ON my_app_db.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES; -- Veritabanından çıkış EXIT; ``` Bu adımlar, 2026 yılında MySQL'i bir Ubuntu sistemine kurmak ve temel bir kullanıcı ile veritabanı oluşturmak için yeterlidir. Daha detaylı yapılandırma ve optimizasyonlar için resmi dokümantasyonu incelemeniz önemlidir. ### BÖLÜM 6 - Temel Kullanım ve Örnekler (Core Usage) MySQL'de veri manipülasyonu ve sorgulama, SQL komutları aracılığıyla gerçekleştirilir. Bu bölümde, CRUD (Create, Read, Update, Delete) işlemleri ve indeksleme gibi temel kullanım örneklerini inceleyeceğiz. #### Örnek 1: Tablo Oluşturma ve Veri Ekleme (CREATE & INSERT) **Problem:** Bir `urunler` tablosu oluşturmak ve içine yeni ürünler eklemek istiyoruz. **Çözüm:** Aşağıdaki SQL komutlarını kullanabilirsiniz. ```sql USE my_app_db; CREATE TABLE urunler ( id INT AUTO_INCREMENT PRIMARY KEY, ad VARCHAR(255) NOT NULL, fiyat DECIMAL(10, 2) NOT NULL, stok INT DEFAULT 0, olusturma_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); INSERT INTO urunler (ad, fiyat, stok) VALUES ('Laptop X', 15000.00, 10), ('Klavye Y', 850.50, 50), ('Mouse Z', 250.00, 100); ``` #### Örnek 2: Veri Sorgulama (READ - SELECT) **Problem:** `urunler` tablosundaki tüm ürünleri veya belirli kriterlere uyan ürünleri listelemek istiyoruz. **Çözüm:** `SELECT` ifadesiyle verileri çekebiliriz. ```sql -- Tüm ürünleri listeleme SELECT * FROM urunler; -- Fiyatı 1000 TL'den yüksek olan ürünleri listeleme SELECT ad, fiyat FROM urunler WHERE fiyat > 1000; -- Stokta olan ürünleri fiyata göre azalan sıralama SELECT ad, fiyat, stok FROM urunler WHERE stok > 0 ORDER BY fiyat DESC; ``` #### Örnek 3: Veri Güncelleme (UPDATE) **Problem:** Bir ürünün fiyatını veya stoğunu güncellemek istiyoruz. **Çözüm:** `UPDATE` ifadesi ve `WHERE` koşulu ile belirli kayıtları güncelleyebiliriz. ```sql -- 'Laptop X' ürününün fiyatını güncelleme UPDATE urunler SET fiyat = 14500.00 WHERE ad = 'Laptop X'; -- 'Klavye Y' ürününün stoğunu artırma UPDATE urunler SET stok = stok + 5 WHERE ad = 'Klavye Y'; ``` #### Örnek 4: Veri Silme (DELETE) **Problem:** Artık satılmayan veya stokta kalmayan bir ürünü veritabanından silmek istiyoruz. **Çözüm:** `DELETE FROM` ifadesi ve `WHERE` koşulu ile kayıtları silebiliriz. ```sql -- Stokta olmayan 'Mouse Z' ürününü silme DELETE FROM urunler WHERE ad = 'Mouse Z' AND stok = 0; ``` #### Örnek 5: İndeks Oluşturma **Problem:** Büyük bir tabloda belirli sütunlar üzerinde sıkça arama yapıldığında sorgu performansını artırmak. **Çözüm:** `ad` sütunu üzerinde bir indeks oluşturarak arama hızını artırabiliriz. ```sql -- 'ad' sütununa indeks ekleme CREATE INDEX idx_urunler_ad ON urunler (ad); -- Fiyat ve stok sütunlarına birleşik indeks ekleme (eğer bu ikili sıkça birlikte sorgulanıyorsa) CREATE INDEX idx_urunler_fiyat_stok ON urunler (fiyat, stok); ``` Bu temel örnekler, MySQL ile günlük operasyonlarınızda karşılaşacağınız en yaygın senaryoları kapsamaktadır. Gerçek dünya uygulamalarında bu komutları güvenli ve optimize bir şekilde kullanmak için best practices'leri uygulamak hayati önem taşır. ### BÖLÜM 7 - İleri Seviye Teknikler (Advanced Patterns) MySQL'de performansı ve ölçeklenebilirliği artırmak için ileri seviye teknikler kullanmak, büyük ve yoğun trafikli uygulamalar için kaçınılmazdır. Bu bölümde, veritabanı mimarisini güçlendirecek bazı gelişmiş yaklaşımları inceleyeceğiz. #### 1. Veritabanı Replikasyonu (Replication) **Amaç:** Okuma yükünü dağıtmak, veri yedekliliği sağlamak ve felaket kurtarma yeteneklerini artırmak. **Çözüm:** MySQL'de Master-Slave replikasyon yaygın olarak kullanılır. Master sunucu tüm yazma işlemlerini (INSERT, UPDATE, DELETE) yaparken, bu değişiklikler Slave sunuculara asenkron veya senkron olarak kopyalanır. Uygulama, okuma sorgularını Slave sunuculara yönlendirerek Master üzerindeki yükü azaltır. ```sql -- Master sunucuda binlog'u etkinleştirme -- my.cnf dosyasına ekleyin: -- log_bin = mysql-bin -- server_id = 1 -- Slave sunucuda replikasyonu başlatma CHANGE MASTER TO MASTER_HOST='master_ip_adresi', MASTER_USER='repl_user', MASTER_PASSWORD='repl_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=123; START SLAVE; ``` > **Pro Tip:** 2026 itibarıyla MySQL 8.x'te Group Replication, yüksek kullanılabilirlik ve otomatik failover için daha gelişmiş bir çözüm sunmaktadır. Bu, özellikle kritik iş yükleri için değerlendirilmelidir. #### 2. Veritabanı Bölümleme (Partitioning) **Amaç:** Çok büyük tabloları daha küçük, yönetilebilir parçalara bölerek sorgu performansını artırmak ve bakım işlemlerini kolaylaştırmak. **Çözüm:** Bir tabloyu belirli bir kritere (örneğin tarih aralığı, ID aralığı) göre fiziksel olarak birden fazla parçaya ayırabilirsiniz. Bu, özellikle `WHERE` koşullarında sıkça kullanılan sütunlar için faydalıdır. ```sql -- RANGE ile tablo bölümleme örneği CREATE TABLE logs ( id INT NOT NULL, log_date DATE NOT NULL, message VARCHAR(255) ) PARTITION BY RANGE (YEAR(log_date)) ( PARTITION p2024 VALUES LESS THAN (2025), PARTITION p2025 VALUES LESS THAN (2026), PARTITION p2026 VALUES LESS THAN (2027), PARTITION pmax VALUES LESS THAN MAXVALUE ); ``` Bu örnekte, `logs` tablosu `log_date` sütunundaki yıl değerine göre bölümlere ayrılmıştır. Bir sorgu belirli bir yıla ait logları istediğinde, MySQL sadece ilgili bölümü tarayarak performansı artırır. #### 3. Sharding (Yatay Bölümleme) **Amaç:** Veritabanını birden fazla sunucuya dağıtarak ölçeklenebilirliği artırmak ve tek bir sunucunun limitlerini aşmak. **Çözüm:** Sharding, uygulama katmanında veya özel proxy'ler aracılığıyla uygulanır. Veriler, belirli bir 'shard key' (örneğin `user_id`) kullanılarak farklı veritabanı sunucularına dağıtılır. Bu, tek bir veritabanı sunucusunun kaldırabileceği işlem yükünü katlayarak artırır. ```javascript // Pseudo-kod: Uygulama katmanında sharding mantığı function getDatabaseConnection(userId) { const shardKey = userId % NUM_SHARDS; // NUM_SHARDS: toplam shard sayısı switch (shardKey) { case 0: return connectToShard0(); case 1: return connectToShard1(); // ... default: return connectToDefaultShard(); } } // Kullanım örneği const userDb = getDatabaseConnection(12345); userDb.query('SELECT * FROM users WHERE id = 12345'); ``` Sharding, mimari karmaşıklığı artırsa da, ekstrem ölçeklenebilirlik gerektiren uygulamalar için vazgeçilmez bir tekniktir. Bu tekniklerin doğru uygulanması, MySQL'in potansiyelini tam olarak kullanmanızı sağlar ve 2026'nın zorlu performans beklentilerini karşılamanıza yardımcı olur. ### BÖLÜM 8 - Best Practices & Anti-Patterns Veritabanı optimizasyonunda doğru yaklaşımları benimsemek kadar, kaçınılması gereken anti-pattern'ları bilmek de önemlidir. İşte 2026 yılı için MySQL best practices ve yaygın anti-pattern'lar: #### ✅ Best Practices * **İndeksleri Akıllıca Kullanın:** Sıkça sorgulanan sütunlara ve `WHERE`, `JOIN`, `ORDER BY` clause'larında kullanılan sütunlara indeks ekleyin. Ancak gereksiz indekslerden kaçının, çünkü yazma işlemlerini yavaşlatır ve disk alanı kaplar. * **Sorguları Optimize Edin:** `EXPLAIN` komutunu kullanarak sorguların nasıl çalıştığını analiz edin. `SELECT *` yerine sadece ihtiyacınız olan sütunları seçin. `JOIN` işlemlerini optimize edin ve alt sorgulardan mümkün olduğunca kaçının veya bunları `JOIN`'lere dönüştürün. * **Veri Tiplerini Doğru Seçin:** Sütunlar için en uygun ve en küçük veri tipini kullanın. Örneğin, `INT` yerine `TINYINT` veya `SMALLINT` kullanmak disk alanından tasarruf sağlar ve performansı artırır. `VARCHAR` için uygun bir uzunluk belirleyin. * **Bağlantı Havuzlaması (Connection Pooling) Kullanın:** Her istek için yeni bir veritabanı bağlantısı açmak yerine, mevcut bağlantıları yeniden kullanarak bağlantı kurma maliyetini azaltın. Bu, uygulama sunucunuzun veritabanı üzerindeki yükünü önemli ölçüde hafifletir. * **Düzenli Yedekleme Yapın:** Veri kaybını önlemek için düzenli ve otomatik yedekleme stratejileri uygulayın. Yedeklemelerinizi farklı fiziksel konumlarda saklayın ve geri yükleme işlemlerini test edin. * **Güvenlik Güncellemelerini Takip Edin:** MySQL'in en güncel kararlı sürümünü (2026 itibarıyla MySQL 8.x) kullanın ve güvenlik yamalarını düzenli olarak uygulayın. Bu, bilinen güvenlik açıklarına karşı korunmanızı sağlar. * **Minimum Yetki Prensibini Uygulayın:** Uygulama kullanıcılarına sadece ihtiyaç duydukları minimum veritabanı yetkilerini verin. `GRANT ALL PRIVILEGES` yerine spesifik `SELECT`, `INSERT`, `UPDATE`, `DELETE` yetkileri atayın. * **Prepared Statement'lar Kullanın:** SQL enjeksiyon saldırılarını önlemek ve sorgu performansını artırmak için Prepared Statement'lar (veya parametreli sorgular) kullanın. Bu, güvenlik için kritik bir adımdır. #### ❌ Anti-Patterns * **`SELECT *` Kullanımı:** Her zaman tüm sütunları çekmek, gereksiz veri transferine ve daha yavaş sorgulara yol açar. Sadece ihtiyacınız olan sütunları belirtin. * **N+1 Sorgu Problemi:** Bir ana sorgunun döndürdüğü her kayıt için ek sorgular çalıştırmak. Bu durum, özellikle ORM kullanırken sıkça görülür ve `JOIN` veya `eager loading` ile çözülmelidir. * **İndeks Olmayan Sütunlarda `ORDER BY` veya `WHERE` Kullanımı:** Büyük tablolarda indekslenmemiş sütunlar üzerinde sıralama veya filtreleme yapmak tam tablo taramasına neden olur ve performansı düşürür. * **Transaction'ları Uzun Süre Açık Tutmak:** Açık transaction'lar, veritabanı kilitlenmelerine ve diğer işlemlerin beklemesine neden olabilir. Transaction'ları mümkün olduğunca kısa tutun. * **Veritabanı Sunucusunu Uygulama Sunucusu Olarak Kullanmak:** Veritabanı sunucusu sadece veritabanı iş yükleri için kullanılmalıdır. Aynı sunucuda uygulama, web sunucusu veya başka servisler çalıştırmak kaynak çekişmesine yol açar. * **Varsayılan Ayarları Değiştirmemek:** MySQL'in varsayılan yapılandırması genellikle genel amaçlıdır. Uygulamanızın özel ihtiyaçlarına göre `innodb_buffer_pool_size`, `max_connections` gibi ayarları optimize etmeniz gerekir. Bu best practices'leri ve anti-pattern'ları anlamak ve uygulamak, 2026 yılında MySQL veritabanlarınızın hem performanslı hem de güvenli olmasını sağlayacaktır. Ekibimizde büyük ölçekli projelere geçiş sürecinde bu kuralları uygulayarak önemli performans ve kararlılık iyileştirmeleri sağladık. ### BÖLÜM 9 - Yaygın Hatalar ve Çözümleri (Troubleshooting) MySQL kullanırken karşılaşılan bazı yaygın hatalar, geliştiricilerin zamanını alabilir. İşte Stack Overflow'da sıkça sorulan ve üretim ortamında karşılaşılan bazı problemler ve çözümleri: #### 1. Hata: `ERROR 1045 (28000): Access denied for user 'root'@'localhost'` * **Problem:** MySQL'e root kullanıcısı ile bağlanırken erişim reddedildi hatası. * **Sebep:** Yanlış parola girilmesi veya root kullanıcısının yetkilerinin yanlış yapılandırılması. * **Çözüm:** Parolanızı doğru girdiğinizden emin olun. Eğer parolanızı unuttuysanız, MySQL servisini güvenli modda başlatıp parolayı sıfırlamanız gerekebilir. Ayrıca, `sudo mysql -u root -p` yerine `sudo mysql -u root` komutunu kullanarak, Ubuntu'da varsayılan olarak root kullanıcısının `auth_socket` eklentisi ile `sudo` üzerinden parolasız bağlanabildiğini unutmayın. #### 2. Hata: `ERROR 1062 (23000): Duplicate entry '...' for key 'PRIMARY'` * **Problem:** Birincil anahtar (PRIMARY KEY) veya benzersiz indeks (UNIQUE INDEX) tanımlanmış bir sütuna zaten var olan bir değer eklemeye çalışmak. * **Sebep:** `INSERT` veya `UPDATE` işlemi sırasında benzersizlik kısıtlamasının ihlal edilmesi. * **Çözüm:** Veri eklemeden önce kaydın var olup olmadığını kontrol edin (`SELECT`). Eğer kayıt varsa `UPDATE` yapın, yoksa `INSERT` yapın (UPSERT mantığı). Ya da `INSERT IGNORE` veya `ON DUPLICATE KEY UPDATE` gibi ifadeler kullanabilirsiniz. ```sql -- UPSERT örneği INSERT INTO urunler (id, ad, fiyat) VALUES (1, 'Yeni Ürün', 100.00) ON DUPLICATE KEY UPDATE ad='Yeni Ürün', fiyat=100.00; ``` #### 3. Hata: `ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'` * **Problem:** MySQL sunucusuna yerel soket üzerinden bağlanılamıyor. * **Sebep:** MySQL servisi çalışmıyor, soket dosyası yanlış konumda veya izin sorunları var. * **Çözüm:** Öncelikle MySQL servisinin çalışır durumda olduğundan emin olun (`sudo systemctl status mysql`). Eğer çalışmıyorsa başlatın (`sudo systemctl start mysql`). Soket dosyasının konumunu `my.cnf` dosyasında kontrol edebilir veya `mysql` komutuna `--socket=/path/to/mysqld.sock` parametresini ekleyebilirsiniz. #### 4. Yavaş Sorgu Performansı * **Problem:** Sorguların beklenenden daha uzun sürmesi. * **Sebep:** Eksik veya yanlış indeksler, kötü yazılmış sorgular, veritabanı sunucusunun yetersiz kaynakları (CPU, RAM, I/O). * **Çözüm:** `EXPLAIN` komutuyla sorguyu analiz edin. Gerekirse yeni indeksler ekleyin veya mevcut indeksleri optimize edin. `SELECT *` yerine sadece gerekli sütunları seçin. Veritabanı sunucusunun kaynak kullanımını izleyin ve gerekirse artırın. MySQL'in slow query log'unu etkinleştirerek yavaş çalışan sorguları tespit edebilirsiniz. ```sql -- Sorgu planını göster EXPLAIN SELECT * FROM urunler WHERE fiyat > 1000 AND stok > 0; -- Slow Query Log'u etkinleştirme (my.cnf dosyasına ekleyin) -- slow_query_log = 1 -- slow_query_log_file = /var/log/mysql/mysql-slow.log -- long_query_time = 1 ``` Bu hataların anlaşılması ve doğru çözümlerin uygulanması, 2026'da MySQL ile geliştirme yaparken karşılaşabileceğiniz sorunları hızla gidermenize yardımcı olacaktır. ### BÖLÜM 10 - Performans Optimizasyonu MySQL'in performansını en üst düzeye çıkarmak, uygulamanızın genel yanıt süresini ve ölçeklenebilirliğini doğrudan etkiler. İşte 2026 yılı için temel performans optimizasyon stratejileri: #### 1. İndeks Optimizasyonu * **Tek Sütunlu İndeksler:** Sıkça `WHERE` veya `ORDER BY` clause'larında kullanılan sütunlara tek sütunlu indeksler ekleyin. * **Birleşik İndeksler (Composite Indexes):** Birden fazla sütun üzerinde filtreleme veya sıralama yapılıyorsa, bu sütunları içeren birleşik indeksler oluşturun. İndeks sırası önemlidir: en seçici (distinct değeri en çok olan) sütun başta olmalıdır. * **Kaplama İndeksler (Covering Indexes):** Bir sorgunun tüm gerekli sütunlarını içeren indekslerdir. Bu durumda MySQL, ana tabloya erişmek zorunda kalmaz, sadece indeksi okuyarak sorguyu yanıtlar ve I/O maliyetini düşürür. ```sql -- Birleşik indeks örneği: (category_id, price) üzerinde sıkça filtreleme yapılıyorsa CREATE INDEX idx_products_category_price ON products (category_id, price); -- Covering index örneği: Eğer sadece 'name' ve 'price' çekiliyorsa CREATE INDEX idx_products_name_price ON products (name, price); SELECT name, price FROM products WHERE category_id = 5; -- Bu sorgu için eğer category_id de indekste olsaydı daha iyi olurdu: (category_id, name, price) ``` #### 2. Sorgu Optimizasyonu * **`EXPLAIN` Kullanımı:** Her zaman sorgularınızın çalışma planını kontrol edin. `type` sütununda `ALL` veya `index` yerine `ref`, `eq_ref`, `range` gibi değerler görmek istersiniz. `Extra` sütunundaki `Using filesort` veya `Using temporary` ifadeleri genellikle performans sorunlarına işaret eder. * **Alt Sorgulardan Kaçının:** Mümkünse alt sorguları `JOIN`'lere dönüştürün, çünkü `JOIN`'ler genellikle daha verimlidir. * **`LIMIT` ve `OFFSET` Optimizasyonu:** Büyük `OFFSET` değerleri sayfalama yaparken performansı düşürebilir. Bunun yerine, son bilinen ID'yi kullanarak bir sonraki sayfayı çekmek daha verimli olabilir (`WHERE id > last_id LIMIT N`). ```sql -- Yavaş sayfalama (büyük offsetlerde) SELECT * FROM buyuk_tablo ORDER BY id LIMIT 100000, 10; -- Optimize edilmiş sayfalama (eğer id sıralıysa) SELECT * FROM buyuk_tablo WHERE id > (SELECT MAX(id) FROM (SELECT id FROM buyuk_tablo ORDER BY id LIMIT 100000) AS tmp) LIMIT 10; ``` #### 3. Sunucu ve Veritabanı Ayarları * **`innodb_buffer_pool_size`:** Bu, muhtemelen MySQL'deki en önemli performans ayarıdır. InnoDB, verileri ve indeksleri bu bellek alanında önbelleğe alır. Genellikle sunucu RAM'inin %50-70'i bu değere atanmalıdır. Örneğin, 16GB RAM'e sahip bir sunucuda `innodb_buffer_pool_size = 10G` gibi bir değer atanabilir. * **`max_connections`:** Uygulamanızın aynı anda kaç bağlantıya ihtiyacı olduğunu belirler. Çok yüksek bir değer bellek tüketimini artırabilir, çok düşük bir değer ise bağlantı hatalarına yol açabilir. * **`query_cache_size` (MySQL 8.x ve sonrası için DEPRECATED!):** MySQL 8.x'te Query Cache kaldırılmıştır çünkü yüksek eşzamanlılıkta performans sorunlarına yol açıyordu. Yeni projelerde buna güvenmeyin, uygulama katmanında veya Redis gibi harici bir önbellek kullanın. #### 4. Önbellekleme (Caching) * **Uygulama Katmanı Önbellekleme:** Sıkça erişilen ancak nadiren değişen verileri (örneğin kullanıcı profilleri, ürün kategorileri) uygulama katmanında Redis veya Memcached gibi araçlarla önbelleğe alın. * **CDN Kullanımı:** Statik içerikler için CDN (Content Delivery Network) kullanarak veritabanı üzerindeki yükü azaltın. Bu optimizasyon teknikleri, MySQL 8.x ve sonraki sürümlerde veritabanınızın 2026'daki performans beklentilerini karşılamasına yardımcı olacaktır. Ekibimizle birlikte yürüttüğümüz son projelerimizde, indeks ve sorgu optimizasyonları sayesinde veritabanı yanıt sürelerinde önemli iyileşmeler gözlemledik. ### BÖLÜM 11 - Gerçek Dünya Proje Örneği (Mini Project) Bu bölümde, basit bir blog uygulaması için MySQL veritabanı şemasını ve temel CRUD işlemlerini içeren mini bir proje örneği sunacağız. Bu örnek, daha önce öğrendiğimiz best practices'lerin nasıl uygulanabileceğini gösterecektir. **Proje Amacı:** Basit bir blog için kullanıcılar, gönderiler ve yorumları yöneten bir veritabanı. **Dosya Yapısı (Mantıksal):** ``` . # Proje Kök Dizini ├── db_schema.sql # Veritabanı şeması ve başlangıç verileri └── app_queries.sql # Uygulama tarafından kullanılan örnek sorgular ``` #### `db_schema.sql` Bu dosya, veritabanını oluşturur, tabloları tanımlar ve başlangıç verilerini ekler. İlişkisel bütünlüğü sağlamak için `FOREIGN KEY` kısıtlamalarına dikkat edin. ```sql -- Veritabanı oluşturma CREATE DATABASE IF NOT EXISTS blog_db_2026; USE blog_db_2026; -- Kullanıcılar tablosu CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Gönderiler tablosu CREATE TABLE posts ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, title VARCHAR(255) NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Yorumlar tablosu CREATE TABLE comments ( id INT AUTO_INCREMENT PRIMARY KEY, post_id INT NOT NULL, user_id INT NOT NULL, comment_text TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- İndeksler (Performans optimizasyonu için) CREATE INDEX idx_users_email ON users (email); CREATE INDEX idx_posts_user_id ON posts (user_id); CREATE INDEX idx_posts_created_at ON posts (created_at DESC); CREATE INDEX idx_comments_post_id ON comments (post_id); -- Örnek Veriler INSERT INTO users (username, email, password_hash) VALUES ('burakb', 'burak@example.com', 'hashed_password_123'), ('ayse_d', 'ayse@example.com', 'hashed_password_456'); INSERT INTO posts (user_id, title, content) VALUES (1, 'MySQL ile Performans Optimizasyonu', 'MySQL veritabanı performansını artırmak için ipuçları.'), (1, '2026 Web Geliştirme Trendleri', 'Geleceğin web teknolojileri hakkında bir bakış.'), (2, 'Veritabanı Güvenliği Önlemleri', 'Veritabanınızı SQL enjeksiyonundan koruyun.'); INSERT INTO comments (post_id, user_id, comment_text) VALUES (1, 2, 'Çok faydalı bir yazı olmuş, teşekkürler Burak!'), (2, 1, 'Katılıyorum, özellikle AI entegrasyonları çok önemli olacak.'); ``` #### `app_queries.sql` Bu dosya, uygulamanın gerçekleştireceği bazı yaygın sorguları içerir. ```sql USE blog_db_2026; -- Tüm gönderileri yazar bilgisiyle birlikte çekme SELECT p.title, p.content, u.username AS author_username, p.created_at FROM posts p JOIN users u ON p.user_id = u.id ORDER BY p.created_at DESC; -- Belirli bir gönderiyi ve yorumlarını çekme SELECT p.title, p.content, c.comment_text, u.username AS comment_author FROM posts p LEFT JOIN comments c ON p.id = c.post_id LEFT JOIN users u ON c.user_id = u.id WHERE p.id = 1 ORDER BY c.created_at ASC; -- Bir kullanıcının tüm gönderilerini çekme SELECT title, created_at FROM posts WHERE user_id = (SELECT id FROM users WHERE username = 'burakb'); -- Yeni bir yorum ekleme (Prepared Statement ile kullanılmalı) -- INSERT INTO comments (post_id, user_id, comment_text) VALUES (?, ?, ?); -- Bir gönderiyi güncelleme (Prepared Statement ile kullanılmalı) -- UPDATE posts SET title = ?, content = ? WHERE id = ? AND user_id = ?; -- Bir gönderiyi silme (CASCADE sayesinde yorumlar da silinecek) -- DELETE FROM posts WHERE id = ? AND user_id = ?; ``` Bu mini proje, temel MySQL şeması tasarımı, indeksleme stratejileri ve ilişkisel sorgulamanın nasıl yapılacağını göstermektedir. Gerçek bir uygulamada bu sorgular, bir ORM (Object-Relational Mapper) veya doğrudan veritabanı sürücüleri aracılığıyla güvenli bir şekilde yürütülmelidir. ### BÖLÜM 12 - Önemli Noktalar (Key Takeaways) * MySQL, 2026 itibarıyla web uygulamaları için güçlü ve yaygın bir RDBMS çözümüdür. * Performans ve güvenlik, veritabanı yönetiminde öncelikli konular olmalıdır. * `EXPLAIN` komutu, sorgu optimizasyonunun temel aracıdır; her geliştiricinin bilmesi gerekir. * İndeksler, doğru kullanıldığında sorgu hızını önemli ölçüde artırır, ancak gereksiz indekslerden kaçınılmalıdır. * Veri tiplerini doğru seçmek, disk alanı ve bellek kullanımında ciddi tasarruf sağlar. * Prepared Statement'lar, SQL enjeksiyonlarına karşı en etkili savunmalardan biridir. * Replikasyon ve sharding gibi ileri seviye teknikler, yüksek ölçeklenebilirlik ve kullanılabilirlik sunar. * Düzenli yedekleme ve güvenlik güncellemeleri, veri bütünlüğü ve sistem kararlılığı için hayati öneme sahiptir. * Uygulama ve veritabanı katmanında önbellekleme, performansı artırmanın anahtarıdır. ### BÖLÜM 13 - Sık Sorulan Sorular (FAQ - PAA Hedefli) #### MySQL nedir ve ne işe yarar? MySQL, 2026 yılında en popüler açık kaynaklı ilişkisel veritab