mysql-logo.jpgBugünkü yazımda web yazılımı yapanlara yönelik pek görülmemiş bir sorgu türünü paylaşmak istiyorum. PHP web programlama dilinde veritabanı olarak genellikle MYSQL programı kullanılır. Yazdığımız php uygulamalarından mysql e sorgular gönderip gelen sonuçlara göre işlem yaptırırz. Lafı çok uzatmadan konunun ayrıntısına geçmek istiyorum.

Programlama senaryosu: Bir web uygulamanızda kullancı herhangi bir fotografın ayrıntısını görebileceği sayfaya tıklıyor. Bu sayfaya girdikten sonra bir sonraki ve bir önceki fotoğrafı (yada ürünü) sayfa içinde göstermek istiyoruz. Aklınıza hemen bunu yapmakta ne var çok basit bir olay gibi gelebilir. Ama iş birazcık karışık.

Yaptığımız tablo fotograflar tablosu olsun. Her fotoğrafın ” id ” isminde özel numaraları olsun. Yapılabilecek sorgulardan ilk akla gelen Limit özelliğini kullanmak olacaktır. Öğneğin kullanıcı 3 numaralı fotoğrafı seçmiş olsun. Yazdığımı kod bu fotoğraftan bir önceki 2 ve bir sonraki 4 numaralı fotoğrafın bilgisini getirmesi lazım. Ozaman ;

SELECT * FROM fotograflar LIMIT 2, 3

şeklinde yazabiliriz.


Ancak bu tarz bir kodlama sisteminde herzaman düzgün sonuçlar vermemekte. Özellikle 2 numaralı ve 1 numaralı kayıtlarda problem çıkartmatadır. Mağlesef istediğimiz sonucu vermemekte. Ayrıca düzgün bir formül bulsak bile fotoğrafların id numaraları düzenli olmak zorunda. Eğer aradan bazı kayıtlar silinmiş ise bu sorgu iş görmeyecektir.

Fotoğrafların numaralarının sıralı olmamasından dolayı sorgu yaparken bulunduğumuz kayıttan bir öncekini bulmak için, öceki kayıtları büyükten küçüğe tersten sıralayıp ilk olanı seçmemiz lazım. Aynı işlemi bir sonraki kayıtı bulmak için de kayıtları küçükten büyüğe sıralayıp bulduğu ilk sonucu seçmemiz gerekiyor.

Konunun biraz daha alaşılması için şu örneği verebiliriz.
Veritabanında fotograların id leri : 1, 2, 3, 6, 7, 8, 12, 25, 30 gibi olsun. Biz 12 numaralı kayıttan bir önceki ve bir sonraki değeri bulmak istiyoruz. Önceki kayıtı bulmak için

“SELECT id FROM fotograflar WHERE id < 12 ORDER BY id DESC LIMIT 1

bunun sonucunda bize 8 numaralı kayıt gelecektir.

Aynı işlemi bir sonraki kayıtı bulmak için yaparsak

“SELECT id FROM fotograflar WHERE id > 12 ORDER BY id ASC LIMIT 1”

bu sorgunun sonucunda bize 25 numaralı kayıt gelecektir.

Böyle bir sistem işimizi görüyor gibi . Ancak toplamda 3 sorgu yapmak zorunda kalıyoruz. Tek bir sorguda bu işlemleri yapmak istersek şu şekilde yapabiliyoruz

” SELECT @a := 1, ( SELECT id FROM fotograflar WHERE id < @a ORDER BY id DESC LIMIT 1 ) AS prev_id,
( SELECT id FROM fotograflar WHERE id > @a ORDER BY id ASC LIMIT 1 ) AS next_id FROM fotograflar LIMIT 1 ”

(buradaki id ve fotograflar yerlerini kendi ihtiyacınıza göre değiştirip farklı alanlar ekleyebilirsiniz)

Sorgumuzu bu şekilde yaptığımız taktirde prev_id ve nex_id alanlarında gelek sonuçlar bir önceki ve bir sonraki sonuçlar olacaktır. Buradaki @a :=1 ifadesini kullanıcının ayrıntısına bakmak istediği fotoğrafın id numarası olarak seçiyoruz. (örneğin 12 numaralı fotoğraf ise @a := 12 şeklinde yazıyoruz. ) PHP kodu olarak @a := “.$id.” şeklinde kullanabilirsiniz.

Bu sorguyu küçük çaplı veritabanlarında performans olarak makul seviyelerde çalışıyor. Ancak büyük veritabanlarında performans biraz kötü. Kendi test veritabanımda ( 55 mb , 184.000 kayıtlı) yaptığım işlemlerde ortalama 0.0931 sn olarak işlemi sonuçlandırıyor. Aynı işlemi 3 sorgulu modelde yaparsak, select cümlesinin içine yazdığımız her sorgunun tek başına çalıştırılması 0.0004 sn oldu. Yani 3 sorgu için ortalama 0.0012 sn gibi oldukça iyi bir değer elde edebiliyoruz. 3 sorgulu modelin avantajı id sütununun index olarak belirlenmesinden kaynaklanıyor. İndex olan sütunlarda işlem yapmak oldukça hızlı gerçekleşir. Tüm veritabanlarında bu şekilde bir yapı vardır.

Herkeze İyi Çalışmalar…

1 YORUM

CEVAP VER

Please enter your comment!
Please enter your name here