JSON Oyunları PostgreSQL MongoDB’ye karşı — PostgreSQL JSON örnekleri

MongoDB ile ilk tanıştığımda, BSON (JSON’ın modifiye edilmiş şekli) ile hiyerarşiyi de saklama fikrinden ve şemasız, esnek yapısından çok etkilenmiştim. Yeni oyuncağım(NoSQL) eskisine(RDBMS) nazaran çok daha “cool”du. Çalışma prensibini incelediğimde ACID’i kaybettiğimi anladım, eski oyuncağım yenisinden daha sağlamdı ama CAP ve BASE de bir çok proje için makul gözüküyordu. MongoDB ile cicim aylarımız harika geçiyordu, projelere çok hızlı başlanabiliyordu, modellemeye uzun zamanlar harcamak zorunda kalmıyordum, ancak bu kez de proje ortalarına gelindiğinde veritabanı modelimdeki yanlış kurguları düzeltmek zaman almaya başlamıştı. Bu durumun “RDBMS kafasıyla” düşündüğüm için oluştuğunu varsayıyor ve suçu kendime atıyordum. Proje daha da ilerlediğinde bu kez de kompleks sorgular ve detaylı raporlar oluşturmak problem yaratmaya başlamıştı, MongoDB’nin aggregation yeteneği RDBMS’lere göre çok çok zayıftı(Ben 2.2 öncesi ile çalışmıştım, şu an çok daha iyi). Bazı işler için map-reduce kullanmaya başlamıştım ama bu da performans problemleri doğuruyordu. Transaction’ın olmaması, hassas işlemlerde two phase commit kullandığımdan, ekstra iş yükü olarak geri dönmüştü. Join olmaması, zaman zaman yaşadığım memory problemleri, geospatial fonksiyonlar vs.. derken, MongoDB’nin doğru bir trade-off olmadığı fikrine kapılmaya başladım. İhtiyacım olan RDBMS mimarisiyle tutulan ancak JSON anlayabilen, konuşabilen, saklayabilen bir sistemdi. İşte PostgreSQL burada devreye giriyor.

Kafamda deli sorular

MongoDB sadece 5 yaşında olmasına rağmen müthiş başarılar elde etti, birçok devasa şirketin production ortamlarında yer buldu. Ancak ciddi tartışmaları da beraberinde getirdi. Tartışmalara göz atarsanız MongoDB savunucularının fail eden projeleri, “doğru projeye, doğru teknoloji” mottosu ile eleştirdiğini görürsünüz. Ben ise bir projeye doğru teknolojiyi, proje başlangıcında, tüm handikapları ile öngörmenin çok zor bir meziyet olduğunu savunuyorum. Çünkü orta ve ileri fazlarda hatta production ortamında genelde ihtiyaçlar hızla değişebiliyor. Bu durumda “doğru teknoloji” göreceli hale geliyor. Konu veri olunca da 30 yıldır kendini kanıtlamış RDBMS “daha risksiz” bir tercih oluyor.

MongoDB ile yaşadığım tecrübelerden sonra hala MEAN Stack’ı çok eğlenceli buluyor ancak MongoDB’ye karşı kafamda deli sorular barındırıyordum.

2012 Eylül’ünde PostgreSQL 9.2 ile gelen JSON desteğini duymuştum ama deneme ve kullanma fırsatını son bir yıldır bulabiliyorum. İzlenimlerim ise oldukça olumlu.

Yazının bundan sonraki bölümünde MongoDB dedikodusu yapmayı bırakıp PostgreSQL’de nasıl JSON ile çalışabildiğimizden ve kullanışlı fonksiyonlarından bahsedeceğim.

PostgreSQL ve JSON sorguları

Şimdi örnek bir on-the-fly sorgu çalıştıralım.

Bu sonucu JSON olarak alabilmek için, sorguyu bir CTE içine alıyorum ve to_json fonksiyonunu kullanarak JSON'a çeviriyorum;

Ta taaaa! Az önce bir RDBMS size sonucu JSON döndürdü. Bu güzel haber ama malesef hayat bu kadar kolay değil. İşleri biraz karmaşık hale getirmemiz lazım.

Şimdi test yapabileceğimiz ortam hazırlayalım. Bir öğrenci tablomuz ve bir derslik tablomuz olsun. İçlerine de biraz veri ekleyelim.

Nispeten karmaşık bir ortam hazırladık. Şimdi JSON fonksiyonları ile neler yapabildiğimize bakalım.

Yukarıda row_to_json kullanarak yine bir sonuç kümesi döndürdük ancak bu kez her satırı json olarak aldık.

Eğer NoSQL kullanıyor olsaydınız muhtemelen hiyerarşik bir veri talep edecektiniz, örneğin her öğrencinin aldığı dersleri iç içe olarak görmek isteyebilirdiniz. Bu duruma PostgreSQL’in json_agg fonksiyonu çözüm getiriyor. json_agg bir aggregation fonksiyonu ve dersleri öğrencilere göre gruplarsak istediğimiz sonucu elde edebiliriz. Örneğin sorguyu sadece Basketbol dersi alan öğrenciler için çalıştırırsak;

Gördüğünüz gibi to_json,row_to_json veya json_agg gibi fonksiyonlar sayesinde tablolardaki verileri json olarak döndürebildik. Ancak PostgreSQL'in JSON yetenekleri bu kadar ile sınırlı değil. PostgreSQL veri tipi olarak da JSON barındırabiliyor.

PostgreSQL ve JSON veri tipi

Şimdi biraz daha derinleşelim ve JSON veri tipi ile neler yapabildiğimize göz atalım. Önce derslik tablomuza json veri tipinde detay adında bir kolon ekleyelim ve bu kolonu dolduralım;

Şimdi “detay” kolonunu kullanarak nasıl sorgu atabiliriz bir gözatalım. Örneğin, eğer güz döneminde verilen dersleri listelemek istersek;

Eğer Bob Ross’un güz döneminde verdiği dersin öğrenci sayısını getirmek istersek;

Eğer detay alanında “secmeli” tagi olmayan desleri getirmek istersek;

Bu örnekler çoğaltılabilir, peki json içerisindeki bir kırılıma index atmak mümkün mü? Örneğin dönem -> isim kırılımına index atmak istersek;

Şimdi yukarıda denediklerimizi bir araya toplarsak;

Gördüğünüz gibi PostgreSQL JSON anlayabiliyor, saklayabiliyor ve konuşabiliyor. Bu sayede geliştiriciler vertabanı katmanında ne RDBMS’lerin avantajlarından vazgeçiyorlar ne de hiyerarşik json yapılarını kullanma fırsatından.

Yukarıda anlatılanlar, tüm json fonksiyonlarının sadece bir kısmı, diğer fonksiyonlara da göz atmayı ihmal etmeyin.

PotgreSQL-JSON Dökümantasyon

Tabi aklınıza gelen ilk soru işareti performans olacaktır. Ben bir benchmark çalışması yapmadım ama internette yaptığım çok kısa bir aramayla aşağıdaki linklere ulaşmak mümkün.

EnterpriseDB — Postgres Outperforms MongoDB and Ushers in New Developer Reality

Github- EnterpriseDB’nin benchmark çalışmasının kaynak kodu

Reddit — PostgreSQL 9.4 is now faster than MongoDB for storing JSON documents

JSON PostgreSQL’in tek bildiği veri tipi değil, aynı zamanda XML, HSTORE ve JSONB de kullanabilirsiniz. Konuyla ilgili PgCon 2014 sunumuna göz atmanızı tavsiye ederim.

PgCon 2014 — HSTORE, XML, JSON, JSONB OH MY!

Son olarak PostgreSQL 9.4 ile gelen bir takım önemli gelişmeler var;

PostgreSQL 9.4 Increases Flexibility, Scalability and Performance

Son söz

Yazının başında MongoDB ile yaşadığım bir takım tecrübelerden bahsettim ama başlarken niyetim sadece PostgreSQL’in JSON fonksiyonlarından bahsetmekti, bir karşılaştırma yapmak değil. Çünkü altyapı ve yaklaşım olarak tamamen birbirinden farklı iki sistemi birbirleri ile karşılaştırmak, birine haksızlık yapmak olacaktır. Mutlaka NoSQL veritabanlarının kendilerine has(özellikle yazma hızı ve ölçeklenebilirlik konularında) avantajları var. Ancak bu yazı, ihtiyacımız sadece şemasız tasarım ise, bunu RDBMS’lerde de bulabileceğimizi gösteriyor.

Proje başlangıcında veritabanına karar vermek ağır bir karar. Benim naçizane tavsiyem tüm sistemlerin güçlü ve zayıf yanlarını öğrenmeniz ancak karmaşıklığını öngöremediğiniz durumlarda tercihinizi yetenekli RDBMS’lerden yana kullanmanız olacaktır.

Kolay Gelsin.


Originally published at www.eferhatg.com on February 24, 2015.