MySQL’de “join” kullanımı

Date02 / Mayıs / 2008 Author İsa Engiz    Category mysql     Tags , Yorumlar13 Yorum Yapilmis.

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.

join-resim

İ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.

- Bu blogda yer alan yazıları RSS ile takip edebilirsiniz. RSS aboneliği için tıklayın.

- 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ış.

  • emrah üstün 03 Mayıs 2008, 13:24

    bir anlatım da şurada var.

  • emre 03 Mayıs 2008, 23:45

    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?

  • İsa 04 Mayıs 2008, 09:13

    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.

  • deniz 28 Kasım 2008, 15:01

    gerçekten çok faydalı oldu teşekürler

  • Ahmet 18 Aralık 2008, 02:15

    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'];

  • İsa Engiz 18 Aralık 2008, 21:57

    İş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.

  • mirc 09 Ocak 2009, 11:23

    tskler guzel bilgiler sitenizde wordpressle ilgili paylasımlarda verirseniz sevinirim (:

  • gebze 28 Ocak 2009, 13:42

    EVET GÜZEL BİR PAYLASIM OLMUS.

  • ozi 26 Şubat 2009, 17:03

    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'].”";
    }

  • Can 06 Mayıs 2009, 13:30

    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.

  • yeni basladim 15 Mayıs 2009, 00:13

    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 :D

  • Codderol 10 Mayıs 2010, 22:59

    çok teşekkürler bu çalışma bana çok yardımcı oldu….

  • beyo 29 Mayıs 2010, 09:26

    emeğine sağlık, temiz bir anlatım olmuş

görüşünü belirt

Spam Protection by WP-SpamFree

Arama


E-Posta Aboneliği


RSS Aboneliği

En Çok Yorumlanan Yazılar

Etiketler

404 ajax apache arama butonu as astrofizik açık kaynak banner blogger blogger/blogspot Blogger / Blogspot blogspot case chmod css date dosya yükleme editör etiket etkinlik favicon featured form ftp galeri Genel gimp hata sayfası header htaccess htpasswd ilişkisel veritabanı index innodb javascript join JQuery kategori koodla linux mysql opacity php resim url

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….

Sayfalar


Faydalı Bağlantılar