MySQL’de “join” kullanımı
Veritabanları oluşturulurken asıl düşünülen her zaman dataların okunmasının ne kadar kolay olacağıdır. Tablolar ve veriler buna göre organize edilir, genellikle bu fikir doğrultusunda hareket edilir.

İlişkili veritabanları da okuma işlemini kolaylaştırmak düşüncesi ile oluşturulurlar. Ve iş bunları okumaya geldiğinde yardımımıza “JOIN” yetişir.
Tablolar
Elimizde örnek olarak şu 2 tablonun bulunduğunu varsayalım:
kitaplar:
| id | kitap_isim | yil | sayfa | fiyat | yazarid | yayineviid |
| 1 | saklı ev | 1995 | 255 | 20 | 1 | 2 |
| 2 | son moda | 2002 | 652 | 25 | 2 | 2 |
| 3 | gelecek | 2007 | 214 | 12 | 2 | 1 |
| 4 | bir umut | 2008 | 421 | 22 | 3 | 1 |
yazarlar:
| id | yazar_isim | soyisim | yas |
| 1 | ekrem | sever | 25 |
| 2 | orhan | veli | 35 |
| 3 | orhan | sevgi | 40 |
| 4 | isa | engiz | 23 |
Görüldüğü üzere birbirleri ile ilişkili tablolarımız var. Yapmak istediğimiz ise diyelim ki, bir kitabın yazarının yaşını öğrenmek istiyoruz. Bu durumda imdadımıza JOIN yetişiyor.
INNER JOIN
join kelimesinin yaptığı, adından da anlaşılacağı gibi, iki tabloyu bizim belirlediğimiz koşullarda birleştirmek. 3 farklı join kelimesi bulunmakta, bunlardan birincisi “inner join”.
Şu sql cümlesini ele alarak başlayalım:
SELECT kitaplar.kitap_isim, yazarlar.yas FROM kitaplar INNER JOIN yazarlar ON kitaplar.yazarid = yazarlar.id
bu kodun bize cevabı şu tablo olacaktır:
| kitap_isim | yas |
| saklı ev | 25 |
| son moda | 35 |
| gelecek | 35 |
| bir umut | 40 |
Yaptığımız şey, çok basit, “select * from” derken yıldız yerine bize geri dönülmesini istediğimiz alanları yazıyoruz, bunu yazarken kuralımız ise; “tabloismi.alanismi” önce tablo ismini yazıyoruz sonra nokta, sonra alanismi. Biz burada iki tane alan belirledik. Ardından birinci tablomuzu yazıyoruz, sonra “INNER JOIN yazarlar” diyoruz. (hangi tablo ismini önce yazdığımız, inner join kullanırken farketmiyor.) Ardından iki tablonun birleşme şartını belirtiyoruz: “ON yazarlar.id = kitaplar.yazarid” Sonuç olarak bize kitap isimleri ve yazarının yaşı geri dönmüş oluyor.
LEFT JOIN
İki tabloyu birleştirmenin ikinci yolu ise “LEFT JOIN” kullanmak.
Aşağıdaki sql cümlesini ele alalım:
SELECT kitaplar.kitap_isim, yazarlar.yazar_isim FROM kitaplar LEFT JOIN yazarlar ON yazarlar.id = kitaplar.yazarid
Bu kodun da cevabı şu olacaktır:
| kitap_isim | yazar_isim |
| saklı ev | ekrem |
| son moda | orhan |
| gelecek | orhan |
| bir umut | orhan |
Aslında kodun yaptığı iş, bir önceki inner join’in yaptığı iş ile neredeyse aynı, ancak left join, soldaki tablonun tamamını alır. Bu sql cümlesinde “kitaplar LEFT JOIN yazarlar” kitaplar soldaki tablo ve bu tablonun tamamı sonuç tablosunda yer alır. Şu anki sql cümlemizde bu bir sakınca yaratmadı ancak yazarı olmayan bir kitap olsaydı, yazar sütununda “null” yazacaktı. Bir sonraki örnekte bu daha rahat görülebilir.
RIGHT JOIN
Left join ile right join hemen hemen aynıdırlar, right join cümlesinin yaptığı iş sadece sağdaki tablonun tamamını almak.
Aşağıdaki sql cümlesini ele alalım:
SELECT kitaplar.kitap_isim, yazarlar.yazar_isim FROM kitaplar RIGHT JOIN yazarlar ON yazarlar.id = kitaplar.yazarid
Bu sql cümlesinin cevabı ise:
| kitap_isim | yazar_isim |
| saklı ev | ekrem |
| son moda | orhan |
| gelecek | orhan |
| bir umut | orhan |
| NULL | isa |
Görüldüğü gibi sağda yer alan yazarlar tablosunun tamamını sonuç olarak aldı ve yazara karşılık gelen bir kitap bulunmadıysa ilgili alanın değerini “null” olarak atadı.
Sonuç
İlişkili veritabanlarında “join” cümleleri çok işe yarar, ve genellikle “inner join” pek çok kez kullanılır. Left join ile right join birbirlerine benzerler, sadece biri soldaki, diğer sağdaki tablonun tamamını alır ve yukarıdaki örnekte olduğu gibi, eğer ilgili yazarın her hangi bir kitabı yoksa, geri döndürdüğü değerlerde “null” kelimesine rastlanabilir.
- Ya da bu blogda yer alan bütün yazıları içindekiler sayfasında görüntüleyebilirsiniz. Tıklayın!
MySQL’de “join” kullanımı yazısına 13 Yorum yapılmış.
görüşünü belirt
Arama
E-Posta Aboneliği
RSS Aboneliği
En Çok Yorumlanan Yazılar
- Ajax ile dinamik listeleme (22)
- Blogger’da “devamını oku” bağlantısı (21)
- MySQL’de Transaction ve PHP ile kullanımı (16)
- PHP ile sınırsız alt kategori mantığı (16)
- MySQL’de “join” kullanımı (13)
- Kullanıcı dostu url hazırlamak (12)
- PHP’nin (muhtemelen) az bilinen 10 özelliği (12)
- Kullandığınız programlama dili ne kadar popüler? (12)
- .htaccess konuları [Giriş] (11)
- Blogger’da arama kutusu ekleme (10)
Etiketler
Son Yorumlar
- Fatih: Açıkçası sitenizi yeni keşfettim ve gerçekten beğendim. Kaynak ve tutorial ihtiyacı olduğunda yabancı blog...
- beyo: emeğine sağlık, temiz bir anlatım olmuş
- gokhan: güzel bir anlatım yapmışsın.. devamını bekleriz.. kolay gelsin
- web yazılım şirketi: google blog araması ile .net üzerinden hizmet veren web yazılım şirketi ararken tesadüfen bu web...
- Codderol: çok teşekkürler bu çalışma bana çok yardımcı oldu….
02 / Mayıs / 2008
bir anlatım da şurada var.
BlueHost, bazen CPU’ya fazla yükleme var diyerek 60 saniyeliğine siteyi askıya alıyordu ve yardımdakiler mysql_slow_queries.log dosyasını inceleyin diyorlardı.
Orada uzun süre sorgular listelenmiş ve bazılarında bolca JOIN geçiyor. Inner, left vs. bunlarda nesi diyordum.
Verdiğiniz bilgiler hayli faydali oldu. Teşekkürler.
Peki null döndürmemesi ya da daha performaslı olmaı için nasıl bir sorgu cümleciği kurmak sağlıklı olur?
Yazının işinize yaramasına çok sevindim.
“NULL” döndürmemesi için yapılabilecek 3 şeyden birincisi “inner join” kullanmak. inner join iki tabloyu, birbirleri ile alakalı olan satırlara göre birleştirir, bir tablodaki değerin diğer tabloda karşılığı yoksa (bu yazıda verdiğim örneğe göre, İsa adlı yazarın kitabı yok mesela) o değeri sonuç tablosuna katmaz, böylece “NULL” değerler oluşmamış olur.
Ama “left join” veya “right join” kullanımında sonuç tablosunun “NULL” değer içermemesi için yapılabilecek tek şey var, iki tabloda da ilişkili değerlerin eksiksiz olarak tanımlanması. (isa isimli yazarın da kitabının bulunması gerekir…)
Yapılabileceklerden bir diğeri ise sorgu cümlesinde “WHERE” kullanmaktır, böylece “NULL” değere sahip alanları sonuç tablosundan çıkarabiliriz.
Join ile ilgili olarak performansı arttırabilecek tekniklerden birincisi tüm alanları sonuç tablosuna katmamaktır. “SELECT * FROM” derken yıldız yerine, işimize yarayacak alanları belrtmeliyiz, bu, sonucun daha çabuk dönmesini sağlayacaktır.
MySQL performansını arttırmak içinse yapılabilecekler oldukça çoktur. Bunlardan en etkilisi ve ilk akla geleni “MySQL’de indexleme”dir. Bu konuda yazdığım şu yazıya bakabilirsiniz. Bir diğer method da “MySQL’de ön belleğe alma”dır, buna da inşallah sonraki yazılarda değinmek istiyorum.
Kolay gelsin.
gerçekten çok faydalı oldu teşekürler
Peki bu yöntem ile amatör olan şu yöntemin arasındaki performans farkı ne kadardır? Birinde işlemi tek sorguda, diğerinde iki sorguda yapıyoruz. Ancak diğerinde de bir sorguda iki işlem yaptırıyoruz.
$sorgu=mysql_query(“Select id,yazar_id,kitap_adi from kitaplar where id=’10′ limit 1);
$sonuc=mysql_fetch_array ($sorgu);
$yazar_id=$sonuc['yazar_id'];
$sorgu=mysql_query(“Select yazar_id,yazar_adi from yazarlar where yazar_id=’$yazar_id’ limit 1);
$sonuc=mysql_fetch_array ($sorgu);
$yazar_adi=$sonuc['yazar_adi'];
İşlemi tek sorguda yapmak her zaman daha performanslı olur. Ancak ne kadar performanslı olacağı başka kriterlere dayanır.
Bunların başında indexlenen alanların sorgularda kullanılması gelir.
Bir diğer unsurda tabloda kaç tane kayıt olduğudur.
Toplam kayıt sayısı, sorguları iç içe yazdığımızda bile performans açısından sorun oluşturabilir. Ben daha önceden indexlenen alanların sorgularda doğru kullanılması ile iç içe sorguların bile daha performanslı olacağını düşünürdüm, ancak bir arkadaşımın deneyimine göre, toplam kayıt sayısı 1-2 milyonu bulduğunda iç içe sorgular da bile performans kaybı yaşanmakta. İndex alanları doğru kullanılmış olsa bile. Bunun yerine join kullanmanın daha performanslı olacağı görüşü hakimdi.
Performansı ise phpmyadmin programında sorgu sürelerini karşılaştırarak öğreniyoruz. Siz de sorgu sürelerini karşılaştırarak performans optimizasyonu yapabilirsiniz.
tskler guzel bilgiler sitenizde wordpressle ilgili paylasımlarda verirseniz sevinirim (:
EVET GÜZEL BİR PAYLASIM OLMUS.
bilgilerinizi paylaştığınız için teşekkürler, aşağıdaki şekilde verileri alıyorum ancak çıktı sayfasında her bilgiyi ikişer defa ekrana yazıyor nerede hata yapıyorum yardımcı olursanız sevinirim
$sorgu = mysql_query(“SELECT * FROM yorumlar inner join kategori limit 10″);
while($yaz = mysql_fetch_array($sorgu))
{
echo “Son Yorumlar” . $yaz['yorum'] . “yazan: “.$yaz['yazarismi'].”";
}
Hocam benim kitaplar tablomda 20 tane satır var. Bir sayfada tüm bu satırlardan veri çekeceğim. Bunlardan sadece ikisinin yazarlar tablosunun yazar satırı ile eşleşmesi lazım. Peki eşleşmesi gerekmeyen satırları nasıl çekeceğim. CPU’yu yormadan işin içinden çıkmak istiyorum.
Can bey dert ettiginiz seye bakin allah askina
tablonuzda yirmi kayit var ve CPU`nun yorulmasindan endise ediyorsunuz.
Efendim verilen bilgiler size yaramaz. Bu bilgiler db sinde milyon kayit tutanlari alakadar ediyr
çok teşekkürler bu çalışma bana çok yardımcı oldu….
emeğine sağlık, temiz bir anlatım olmuş