Etiket arşivi: Veritabanı

MySQL Türkçe Karakter İlk Harf Sıralaması

Published / by Uğur Özşahin / Leave a Comment

    PHP ve MySQL e geçiş sürecim ve bu konulardaki eksikliklerim gün geçtikçe kapanıyor. Ancak sancılı bir dönem olduğu en azından benim için gün gibi ortada. Her yazdığım koddan sonra yada yazmak istediklerim için araştırmaya girişmek beni yavaşlatan başlıca sebeplerden. Fakat ilk kompleks projemi bu şekilde hazırlıyor olmamın çok önemli bir nedeni var. Yıllarca WEB konusunda VB Script ve Access veritabanı ile uğraşmış biri olarak, PHP ve nimetlerinden yararlanmanın tek yolunun bu şekilde kodlama yapmaktan geçiyor olması. Çünkü daha önce PHP ile ilgili her ne kadar bir kitap bitirmiş olsamda, düzey bakımından kesinlikle ihtiyacımı karşılayabilecek seviyede değildi. Dedim ya basit PHP kodlamalarımı belki bu kitap sayesinde yaptım, ancak işin içine daha özgün ve karmaşık yapılar girdiğinde, muhtemelen hiç bir kitap ihtiyaçları karşılayacak yeterliliğe sahip olmuyor.

    Başlıkta anlatmak istediğimi kısaca daha anlaşılabilir biçimde açıklayayım. PHP ve MYSQL ile yapmak istediğim şu, öncelikle elimde bir tablom ve listelemem gereken verilerim var. Listeleme koşulum ise her verinin baş harfinin, alfabetik bir düzen içerisinde web sayfasında görüntülenmesi. Örnek vermek gerekirse, ziyaretçi ’A’ harfine göre listeleme yapmak istediğinde, sonuçlar içerisinde yalnızca ’A’ ile başlayan verinin görüntülenecek olması. Aslında yapmak istediğim şey son derece basit ki, zaten istediğimi bir parçada almış olmama rağmen, işin içine Türkçe karakterle başlayan veriler girdiğinde sonuç beklentilerim ile uyuşmuyordu. Yine örnek verecek olursam, ’İ’ harfine göre bir listeleme yapmak istediğimde, liste içerisinde ’I’ ile başlayan verilerde yer alıyordu. Neyse ki sorunun çözümünü yine kendim buldum. Aslında tüm sıkıntı veritabanında yer alan tabloların kendine has özelliklerinden kaynaklanıyormuş. Prensip olarak tablo karakter setlerini ’utf8’ olarak belirlerim. Collation (Karşılaştırma) değerini ise ön tanımlı olan ’utf8_general_ci’ olarak bırakırdım. İşte hata tam olarak bu noktada başlıyor, Collation özelliğini ön tanımlı olarak bırakmak yerine ’utf8_turkish_ci’ olarak ayarlamamın istediğim sonucu sağladığını gördüm. Ancak belirtmeliyim ki, ’utf8_turkish_ci’ ayarı, uluslararası projelerde neler götürür kestiremiyorum. Bu yüzden sanırım, yabancı dilde hazırladığım sitelerde ’utf8_general_ci’ yada ’utf8_unicode_ci’ ayarlarını kullanmaya devam edeceğim.

Önemli Not: Yalnız bu değişikliği eğer fulltext indeks içerikli tablolarda yapmak isterseniz bazı hatalar ile karşılaşabilirsiniz. Bu yüzden öncelikle fulltext indeksleri kaldırmanızı ve Collation (karşılaştırma) ayarlarını yaptıktan sonra fulltext indeksleri tekrar tanımlamanızı öneriyorum.

Char ve Varchar veritipleri arasındaki farklar

Published / by Uğur Özşahin / Leave a Comment

    Veritabanı ile uğraşanlar bilirler, veritipleri performans ve veri kapasitesi bakımından önemli bileşenlerdir. Oluşturulan alanlarda öncelikli olarak işimize uygun olacağını düşündüğümüz veritipleri ile çalışmak hedeflerimizin başında gelir. Yakın zamanda  Char ve Varchar veri tipleri arasındaki farklar konusunda yeterli bilgiye sahip olmadığımın farkına vardım ve hem not almak, hemde paylaşmak maksadı ile buraya yazmak istedim.

    Char ve Varchar veritipleri arasındaki farkları bir liste halinde aşağıda bulabilirsiniz.

  • Char veritipi 0 ile 255 karakter arasında veri tutabilirken, Varchar veritipi MySQL v5,03 ten itibaren 0 ile 65,535 karakter arasında veri tutabilmektedir. MySQL’in önceki versiyonlarda ise Char veritipi ile aynı kapasiteye sahiptir.
  • Char veritipi, tanımlandığı kadar kapasitenin tamamını kullanır. Örnek olarak siz 50 karakterlik bir alan tanımlamışsanız, bu alana 20 karakter bile girmiş olsanız, geriye kalan sağdan 30 karakterlik alan boşluk karakteri ile doldurulur. Varchar veritipi ise değişken bir yapıya sahiptir ve tanımlanan karakter katarına kadar olan boyutta değişkenlik gösterebilir. Yine örnek vermemiz gerekirse, 50 karakterlik bir alan için 30 karakter girdiğinizde hafızada sadece 30+1 karakterli bir alan kaplar.
  • Char veritipinin kullanım alanı olarak sabit uzunluklu veri yapıları gösterilebilir. (Örn: telefon numaraları, kredi kartı no vb.) Varchar ise değişken uzunluklu veri yapıları için uygundur. (Örn: isim, mail vb.)
  • Ayrıca bir tabloda varchar veritipinde tek bir alan bile yer alsa, bu aynı tablodaki diğer char veritipi ile belirlenmiş alanlarında Varchar biçiminde çalışmasına neden olur.

    Burada bahsettiklerim dışında başka farklılıkların olduğunu biliyorsanız, yorum kısmında belirtebilirsiniz.

mysqli_connect() Fonksiyonu

Published / by Uğur Özşahin / Leave a Comment

    PHP üzerinde uğraştığım ve en çok sorun yaşadığım konulardan biri veritabanlarıdır. Sonuçta bir çok projemin temelinde öyle yada böyle bir şekilde veritabanları söz konusudur. Özellikle PHP söz konusu olduğunda, bu veritabanı meselesi daha çok ön plana çıkmaya başladı. Bildiğiniz gibi günümüzde PHP ile birlikte en çok kullanılan veritabanlarından biri MySQL. Doğal olarak benimde daha çok üzerinde durduğum veritabanlarını oluşturuyorlar. Maalesef her geçen gün bu konuda yeni bir şey öğrenmek ile birlikte, bazı takıldığım noktalarda olmuyor değil.

    Bir arkadaşımdan öğrendiğim bir hazır scripti, kendi serverımda denemek isterken scriptin kurulumu sırasında, veritabanı ile iletişim kurmak için girdiğim ve doğruluğundan tamamen emin olduğum veritabanına erişim bilgilerine rağmen bir problem ile karşılaştım. Daha sonra kurulum dosyasının kodlarını incelediğimde, veritabanı bağlantısı  için mysql_connect() fonksiyonu yerine mysqli kütüphanesinden yararlanılabilmesi için kullanılan mysqli_connection() fonksiyonuna rastladım. Zaten aldığım hatada veritabanı ile bağlantı kurulamadığı yönündeydi. Dolayısı ile tekrar yaptığım incelemelerimde her verinin doğru girilmesine karşın, karşılaştığım sorunun mysqli_connection() fonksiyonunun kullanımı ile ilgili olduğu sonucuna vardım. Yani kısaca mysql_connection() fonksiyonun aldığı parametreler ile mysqli_connection() fonksiyonunun aldığı parametrelerin birbirlerinden bariz farklılıklar barındırdığını anladım.

mysqli_connection();

    mysql_connection() ve mysqli_connection() parametrelerini kısaca açıklayacak olursak;

mysql_connection(server, username, password, new_link, client_flags)


server parametresi: mysql server adresi ve portu
username parametresi: mysql server için kullanıcı adı
password parametresi: mysql server için şifre
new_link ve client_flags parametreleri bizi şimdilik ilgilendirmeyen ve default değerlere sahip parametreler.

mysqli_connection(host, username, passwd, dbname, port, socket)


host parametresi: mysql server
username parametresi: mysql server için kullanıcı adı
passwd parametresi: mysql server için şifre
dbname parametresi: mysql veritabanın adı
port parametresi: mysql server’a ait iletişim port numarası
socket parametresi default değere sahip benimde hakkında pek bilgi sahibi olmadığım başka bir parametre.

    Şimdi diyebilirsiniz, zaten en başta bu iki fonksiyonun aldığı parametrelerin sayıları farklı. Ancak şunu belirtmeliyim bu parametrelerin sayıları farklı olduğu gibi, aynı işleve sahip olması beklenen parametrelerin kullanımında da önemli farklar ortaya çıkmakta. Örnek olarak ben mysql_connection() fonksiyonunda kullanılan server parametresi ile mysqi_connection() fonksyionunda kullanılan host parametresinin aynı olmasını beklerken, ne kadar büyük bir yanılgı içinde olduğumun farkına vardım. Zaten en başta yaşadığım problemin temelinde bu farklılık baş göstermekteydi. Aşağıya örnek olarak iki bağlantı kodu yazacağım:

mysql_connection("localhost:3306","root","xxxx");
fonksiyonu çalışırken

mysqli_connection("localhost:3306","root","xxxx","veritabani");
fonksiyonunun çalışmadığına şahit olacaksınız. Bir önceki paragrafta belirttiğim gibi bunun nedeni ilk parametrenin kullanımının önemli bir şekilde farklı olması. Parametrelerden bahsettiğimde de anlaşılmış olduğunu düşündüğüm bu fark Port parametresinden ileri gelmekte. O parametreyi oraya boşuna sıkıştırmamışlar değil mi? 😉 Fonksiyonun doğru kullanımına örnek verecek olursak;

mysqli_connection("localhost","root","xxxx","veritabani",3306); olmalı.



    İşte yeni öğrenmiş olduğum fonksiyon ile birlikte basit ancak, önemli olduğuna inandığım sorunun çözümü. PHP de fonksiyonlara ait parametre ve diğer bilgilere çabuk ulaşmak istiyorsanız browserınızın (ie, firefox)  adres satırına http://tr2.php.net/ ile birlikte fonksiyonunuzu yazmanız yeterli olacaktır.

Örnek: strtr(); fonksiyonu için http://tr2.php.net/strtr

InnoDB ve MyISAM Veritabanı Motorları

Published / by Uğur Özşahin / Leave a Comment

    Bugün küçük bir araştırma yaparken çok güzel bir inceleme okudum. İncelemenin içeriği PHP ve ASP.NET dillerinde MySQL ve MSSQL (Microsoft SQL) gibi veritabanlarının gösterdiği performans farklılıklarından oluşuyordu. Aslında araştırmam daha çok InnoDB ve MyISAM motorlarının performans farklılıkları ile sınırlıydı. Ancak daha bütünleşik ve farklı platformlarıda içine alan güzel bir inceleme ile karşılaşmak, daha geniş fikir edinebilmem açısından çok yararlı oldu.

    İncelemeyi gerçekleştiren arkadaşımızın adı Görkem PAÇACI. Kendisini şahsen tanımıyorum ancak bu çalışmasından dolayı kutluyorum. İncelemenin benim açımdan eksi tarafı, tüm incelemenin Windows sistemleri üzerinde gerçekleştirilmiş olması idi. Sonuç itibarı ile PHP ile uğraşıyorum ve hosting paketimin bulunduğu server da Linux bir sistem. Böyle olunca inceleme üzerinden sadece küçük bir fikir yürütebiliyorum. Ama windows sistemler üzerinde host sahibi olan arkadaşların ASP.NET MySQL ve MSSQL, PHP MySQL ve MSSQL ilişkileri hakkında ayrıntılı fikir sahibi olabileceğini umuyorum.

    İncelemeyi şuradan indirip okuyabilirsiniz. Daha öncede belirttiğim gibi dökümanın sahibi Görkem Paçacı arkadaşımızdır. Kendisine böyle yararlı bir incelemeyi yaptığı için tekrar teşekkür ediyorum.

    İncelemenin çok kısa bir özetini geçecek olursam. İncelemeye göre bir windows sistem üzerinde, ASP.NET ve MsSQL ilişkisinin diğer tüm ilişki ve yapılara göre daha başarılı olduğu göze çarpıyor. Ciddi bir avantaj farkı var gibi. Ancak daha önce de belirttiğim gibi özellikle PHP MySQL ikilisinin bir Linux sistem üzerinde çok daha farklı bir performans göstereceğini düşünüyorum. Bu arada 2000 satırlık bir veritabanı için windows sistem üzerinde bir MySQL veritabanında, MyISAM motoru InnoDB ye nazaran select ve insert sorgularında daha iyi bir performans gösteriyor. Tabi öğrendiğim kadarı ile InnoDB nin büyük veritabanlarında daha çok tercih edildiği de farklı bir gerçek.

    MyISAM tercihi için 2GB, 4GB ve 5GB gibi üst sınırlar duymuş olmakla beraber, ne kadar itibar edilebilir sınırlar olduklarından da emin değilim. Ancak eğer çok büyük bir veritabanı ile uğraşmıyor ve sürekli veri girişi yada düzenli veri alış verişi gibi ihtiyaçlarınız varsa MyISAM tercihiniz olmalı diye düşünüyorum. Açıkçası bulabildiğim Türkçe kaynaklara ve kısacık da olsa tecrübelerime dayanarak bunu söyleyebilirim. Ayrıca incelemeyi göz attığınızda, insert sorgularında MyISAM ve InnoDB arasında performans bakımından önemli bir fark olduğunun sizde farkına varacaksınız. MyISAM ve InnoDB motorları arasındaki işleyiş farklıkları konusunda da bir araştırma yapmanız çalışmalarınızın güvenliği açısından yararlı olacaktır.

    Eğer sizinde kafanızda InnoDB ile MyISAM kıyaslamasının sonuçları tam olarak oluşmuyorsa incelemeyi kesinlikle gözden geçirmelisiniz. Ayrıca bu yazıyı okuduğunuzda da biraz da olsa fikir sahibi olabileceğinizden eminim. Diğer yandan bu veritabanı motorları hakkında çok daha ayrıntılı bilgiye yazının başında vermiş olduğum linklerden ve şuradan ulaşabilirsiniz.

SQL GROUP BY Kullanımı

Published / by Uğur Özşahin / Leave a Comment

    Geçtiğimiz günlerde ihtiyacım olduğundan dolayı yazmış olduğum bir SQL bloğunda GROUP BY kullanmak zorunluluğu hissettim. Ancak GROUP BY ı daha önce tam olarak kavrayamamış olmanın da etkisi ile bir türlü elde etmek istediğim sonuca ulaşamadım. Tabi doğal olarak internette bir çok yerli yabancı site gezmek zorunda kaldım. Group By ile ilgili olarak yapmış olduğum araştırma sonucu yerli sitelerde (en azından Google ın önümüze sunduğu seçeneklerde) bu bileşenin kullanımı ile ilgili yeterli datanın yer almadığı kanısına vardım. Bunun üzerine de çekmiş olduğum kısa süreli eziyetin başkaları tarafından da çekilmemesi adına blogumda böyle bir yazıya yer verme ihtiyacı hissettim.

    Açıkçası ilk olarak Group By a hangi şartlar altında ihtiyaç duyacağınızı söylemek sanıyorum en mantıklısı olacaktır. Veritabanızda yer alan tablolardan birinde 1000 lerce kayıtın varlığını dikkate alalım. Bu kayıtlar arasında tekrarlı veriler olduğunu ve bunların süzülmesini gerektiren bir durum olduğunu varsayalım. Bu işi SQL dışındaki kod bloklarınız ile pek ala yapabilirsiniz. Ancak tahmin edebileceğinizi umuyorum ki böyle bir durumda yazmış olduğunuz kodun binlerce kayıdın yer almış olduğu veritabanları için büyük bir performans kaybına yol açacağı muhakkaktır. Bu gibi durumlarda SQL dilinin kendisinden yararlanarak, bu dilin getirmiş olduğu faydalardan maksimum şekilde fayda sağlamak en doğru seçim olacaktır.

    Örnek vermem gerekirse diyelim ki veritabanımızda iki tablomuz mevcut ve bu tablolardan birisi yazılarımızın yer aldığı tablomuz diğeri ise yazılarımıza yapılmış olan yorumların tutulduğu tablomuz. Bu iki tablodan hareketle sitemizin ana sayfasında son yapılan yorumları yayınlamak istiyoruz. Ana sayfada yer alacak olan son yorum bölümünün en önemli özelliği ise aynı makaleye yapılmış olan yorumların sadece en son yapılmış olanının yer alması ihtiyacıdır. Yani bir yazımız var ve son derece hareketli bir tartışmaya neden olmakta ve yorumların ardı arkası kesilmiyor. Ana sayfamızda ise bu yazıya ait olan yorumların listesi almış başını gitmiş. Son yapılan yorumlar listesinde o yazıya yapılan yorumların dışında bir yorum bulunmuyor ve biz bunun önüne geçmek istiyoruz. Sadece yazılarımıza yapılmış olan en son yorumların bu listede yer almasını istiyoruz. Böylece hem daha fazla yazıya ulaşılmış oluyor hemde sitemizde lüzumsuz link kirliliği oluşturmamış oluyoruz.

    Şimdi tablo yapılarımızı oluşturalım. Bunlar elbetteki çok basit tablo yapıları olacaktır. Ancak sonuç itibarı ile elde edeceğimiz SQL kodunu kendi tablo yapılarınıza entegre etmekte pek fazla zorlanacağınızı sanmıyorum.
   
    Yazılarımızın yer aldığı tablo tbl_yazi
    Yorumların yer aldığı tablo tbl_yorum
   
    tbl_yazi tablomuzda yer alan alanlar ise id, baslik, yazi
    tbl_yorum tablomuzda ise yorum_id, yazi_id, yorum, yorumcu

Tablolarımızda aşağıdaki gibi verilerin olduğunu varsayalım ve Group By kullanımının sonucunun ne olduğunu örneklendirerek gözleyelim.

tbl_yazi
idbaslikyazi
1SQLbla bla bla
2ASPbla bla bla
3PHPbla bla bla
4VB.NETBla bla

tbl_yorum
yorum_idyazi_idyorumyorumcu
11blayorumcu 1
21bla blayorumcu 2
32blallllllyorumcu 3
42bla bla blayorumcu 1
54blalaya blaya bir hal oldukyorumcu 3

  
    Tablolarımız bunlar ve biz ana sayfamızda belirlediğimiz kriterlerde son yapılan yorumlar listesinin yer alması konusunda kararlıyız. En önemli şartımız ne idi? Listemizde sadece her yazı için yapılmış olan son yorumun yer alacak olmasıydı.

    Şimdide geçelim bunu gerçekleştirecek olan son derece kısa ve kullanışlı SQL kodumuzu vermeye. Aynı zamanda Group By kullanımını iyi bir şekilde açıkladığınıda düşündüğüm bir kod olacak bu. SQL kodumuz sadece tbl_yorum tablosunu kapsayacak, zaten bu bizim için yeterli olacaktır.

    Yukarıdaki kodda dikkat edilmesi gereken Group By kullanımı sırasında SQL kodu içerisinde geçen her alanın Group By parametresinin arkasında yer alması gerektiğidir. Alanlardan herhangi birisi olmadığı taktirde SQL kodumuz hata verecektir. Sonuçta oluşturmuş olduğumuzun kodun tablo çıktısıda aynen aşağıdaki gibi olacaktır.

tbl_yorum
yorum_idyazi_idyorumyorumcu
54blalaya blaya bir hal oldukyorumcu 3
42bla bla blayorumcu 1
21bla blayorumcu 2

      
    Yani son yapılan yorumlar listemizde 3 kayıt yer alacak ve bu kayıtların ilişkili olduğu yazılarımızın tablo gösterimi ise aşağıdaki gibi olacaktır. Yukarıdaki tabloda da görüldüğü üzere 5 yorum arasından sadece 3’ü listelenmiş olup 3 yorumda farklı yazıları işaret etmektedir. Dolayısı ile amacımıza ulaşmış oluyoruz.

tbl_yazi
idbaslikyazi
4VB.NETBla bla
2ASPbla bla bla
1SQLbla bla bla

   Ben yukarıdaki kodda gruplama işlemini yazi_id alanına göre gerçekleştirdim, siz isterseniz gruplama kriterini yorumcu yada diğer benzer veriler içerebilecek alanlara göre düzenleyebilirsiniz. Yorumcu alanına göre gruplandırma yapmak isteseydik kodumuz aşağıdaki gibi olacaktı.

    Size geriye kalan son yapılan yorumlar listenizin link düzeneği kurarak, listenizin keyfini çıkarmaya başlamak olacaktır.