Tamamen SQL ile gerçekleştirilen Advent of Code 2024
(databasearchitects.blogspot.com)- Advent of Code 2024'teki tüm problemler yalnızca saf SQL ile çözülebildi ve asıl nokta, SQL'in genel bulmaca çözümünden farklı bir düşünme biçimini zorlaması
- Küçük ölçekli alan dolaşma problemleri, girdi ayrıştırmadan özyinelemeli sorgu tabanlı arama ve toplamaya kadar SQL içinde nispeten doğal biçimde ele alınabiliyor
- Day 16 gibi durum sayısının büyük ölçüde arttığı problemlerde asıl sorun ifadenin kendisinden çok değerlendirme maliyetiydi; gerçek girdide 200GB'tan fazla bellek gerektirecek kadar verimsizlik oluştu
- Day 23'teki maksimum klik problemi Bron-Kerbosch algoritması ile iyi örtüşüyor, ancak birden çok küme kullanmaya çalışan yapı, tek bir kümeyi aktaran özyinelemeli SQL modeliyle çatışıyor
- SQL ile karmaşık algoritmalar yazmak mümkün, ancak veritabanı içinde çalıştırmanın daha pratik olması için özyineleme sırasında durum güncelleme ve daha zengin durum işleme yetenekleri gerekiyor
Advent of Code 2024'ü yalnızca SQL ile çözmek
- Advent of Code 2024 saf SQL ile çözüldü ve tüm problemler yalnızca SQL kullanılarak çözülebildi
- Tüm çözümler GitHub deposunda açık olarak paylaşılıyor
- Bu yaklaşım, problemleri farklı biçimde düşünmeye zorladı ve birçok durumda SQL beklenenden daha konforlu bir araç oldu
Day 11: Küçük dolaşma problemlerinde SQL'in uyumu
- Day 11'in tam çözümü, bulmaca girdisi de dahil olmak üzere tek bir SQL dosyasından oluşuyor
- Girdi işleme, metni adım adım tablo yapısına dönüştüren bir akış izliyor
- Bulmaca girdisi bir dize olarak tutuluyor
- Girdi ayrı satırlar halinde bölünüyor
- Her karakter koordinat ve değere dönüştürülerek 2D dizi benzeri bir tablo oluşturuluyor
- Algoritma kısmı görece kısa kalıyor
- Alan özyinelemeli sorguyla dolaşılıyor
- Dolaşma sonucundan bulmaca cevabı çıkarılıyor
- Bu tür küçük ölçekli dolaşma işlerinde SQL yeterince iyi çalışıyor
Day 16: Özyinelemeli SQL'de durum saklamanın maliyeti
- Day 16, Day 11'e benzer şekilde bir alanı dolaşıyor ve ziyaret edilen her nokta için minimum dolaşma mesafesini hesaplıyor
- SQL ile ifade etmek kolay, ancak değerlendirme süreci israfçı
- Gerçek bulmaca girdisinde alan büyüdükçe özyinelemeli sorgu çok sayıda durum üretiyor ve saklıyor
- Aslında gereken şey yalnızca özyinelemeli sorgunun son iterasyon sonucu
- Buna rağmen hesaplanan tuple'ların büyük bölümü korunuyor
- Bu yüzden sorgunun çalıştırılması 200GB'tan fazla bellek gerektiriyor
- Özyineleme sırasında iterasyon semantiği (iteration semantic) kullanılırsa aşırı bellek kullanımını azaltmak mümkün
- Umbra bunu yapabiliyor
- Postgres ve DuckDB bunu desteklemiyor
- Bu nedenle bu özellik çözüme dahil edilmedi
Day 23: Birden çok küme gerektiren algoritmalarda sınırlar
- Day 23, seyrek bir grafikte maksimum klik bulmayı gerektiren bir problemdi
- Bu problem Bron-Kerbosch algoritması ile makul biçimde çözülebiliyor
- Ancak bu algoritma birden çok kümeyi korumaya çalışırken, özyinelemeli SQL yalnızca tek bir kümeyi aktarıyor
- Uygulamak mümkün oldu, ancak SQL ifadesi oldukça karmaşıklaştı ve ortaya çıkan kod da pek temiz olmayan bir yapıya dönüştü
Özyinelemeli SQL için gereken ek özellikler
- Karmaşık algoritmalar da SQL ile yazılabilir ve birçok durumda SQL kodu beklenenden daha okunabilir ve yazılabilir çıktı
- Özyinelemeli SQL'de bir durum güncelleme mekanizması olursa daha verimli ve kullanımı daha kolay hale gelebilir
- Özyinelemede daha karmaşık kontrol akışını desteklemek için bir trambolin mekanizması üzerine araştırma sürüyor; bu yaklaşım da faydalı
- Daha karmaşık durum işleme mekanizmalarına da birlikte bakmak gerekiyor
- Az miktarda ek özellikle bile SQL, karmaşık algoritmaları doğrudan veritabanı içinde çalıştırmak için sağlam bir seçenek olabilir
1 yorum
Hacker News yorumları
Böyle bir şeyi başarmak gerçekten ancak olağanüstü biri için mümkün. Saf sanat bu; programlama dünyasında böyle şeyler yeterince yok.
Bu başlığı görünce Taco Bell’in yeni menüsünü gördüğümde verdiğim tepkiye benzer bir tepki verdim. Arzu, utanç ve insan yaratıcılığına duyulan hayranlığın tuhaf bir karışımı.
Advent of Code gibi problemlerde muhtemelen en zor kısım girdiyi ayrıştırmak olur.
Belki tablet arayüzünü kurcalarsanız malzemeleri öğrenebilirsiniz ama şu anda şansa kalmış bir oyun gibi. Ciddi konuşmak gerekirse, https://www.amazon.com/Joe-Celkos-SQL-Smarties-Programming-d... uç düzey SQL zanaatkârlığını öğrenmek için harika bir ders niteliğinde.
HN’in tamamı insan yaratıcılığıyla ilgili bir yer değil mi diye düşünüyorum; hepsini Taco Bell menüsüne bakıyormuş gibi mi karşılamak gerekiyor, emin değilim.
İyi yapılmış. İlk bakışta delilik gibi görünüyor ama büyük SQLin karmaşıklığı barındırmanın en iyi yollarından biri olduğunu düşünüyorum.
Karmaşıklık, problemin kendisi karmaşık olduğu için var. SQL standart, yoğun ifadeli, çok hızlı, gerçekten test edilebilir ve mantıksal bir dil. Herkesin hemen bakımını yapabileceği bir şey değil ama Java’da çok sayıda satır ve fonksiyonla yazıldığında da durum aynı.
SQL’in derin olmasını da seviyorum. 40 yılı aşkın süredir veri dünyasını ayakta tuttuğuna göre insanların uç özellikler istemesi doğal. Oracle’ın model cümleciği, çok boyutlu diziler uygulamaya olanak tanıdığı için sevdiğim özelliklerden biri; bir arkadaşım onunla Conway’in Yaşam Oyunu’nu beklediğimden çok daha az satırla gerçekleştirmişti.
Sonunda bunu native kodla yeniden yazıp 1 saniyenin altına indirdim; işin büyük kısmı aynı sonucu verdiğini kanıtlamak ve benden sonraki kişinin aynı çileyi çekmemesi için test case’leri yazıp dokümante etmekti. Ondan sonra çok fazla iş mantığını SQL’e koymaktan genel olarak kaçınır oldum.
Bana göre karmaşık olan şeylerin hem elle hem otomatik olarak kolayca test edilebilir olması gerekir. SQL’de elle test kolay ama otomatik test, programlama dili koduna kıyasla daha zor. Spagetti kod yığınını daha gevşek parçalara ayırıp bölüm bölüm ele alabilirsiniz; ama birbirine dolanmış SQL spagettisi ile ne yapılır, kestirmek zor.
Satır sayısı arttıkça bug riskinin arttığı sözüne de tamamen katılmıyorum. Çünkü her satır aynı değil. 400 karakterlik tek bir SQL satırının gözle taranıp sorun bulunması, 400 satır Java koduna göre muhtemelen daha zordur; Java’dan birçok nedenle hoşlanmayan biri olarak bile böyle düşünüyorum.
Bu tür dekadan meydan okumaları seviyorsanız, ben bu yıl Advent of Code’u Google Sheets ile denedim.
Sadece 6. güne kadar geldim ve her gün iki yıldızın tamamını da almış değilim. 7. gün çözümümün doğru olduğundan epey eminim ama uzun girdide hücre başına karakter sınırına takıldım.
Keyfini çıkarın. Yalnız mobilde açmamanız iyi olur; bazı sayfalar uygulamayı öldürüyor.
https://docs.google.com/spreadsheets/d/10FY-89y19tnRM_EAAnCd...
Kariyerim boyunca başka herhangi bir kod türünden daha fazla SQL yazdım. Son 5 yılda daha az kullandığım için muhtemelen çoğunu unutmuşumdur ama eskiden gerçekten keyif alırdım.
Yinelemeli düşünmeyi bırakıp küme işlemleriyle düşünmeye başlayınca oldukça doğal ve güçlü hale geliyor.
Şema iyi yapılandırılmışsa ve iş paydaşlarının bakış açısıyla uyumluysa, SQL sorgularıyla tanımlanan iş mantığı oldukça sezgisel olabilir.
Kod, framework’ler, ORM’ler, “en iyi uygulamalar”, kalıplar vb. sonuçta dikkat dağıtan unsurlar. Veriyi veritabanına koyup çıkarmanın milyonlarca yolu var; bitleri taşımak başlı başına düşük değerli bir iş. Basit bir merge ifadesi ya da CSV içe aktarma işiyle çözülebilecek pek çok abartılı yazılım çözümü var.
SQL hakkındaki yanlış anlamaların ve kötü hislerin önemli bir kısmı dağınık şemalarla uğraşmak zorunda kalmaktan doğuyor. Dilin kendisi gerçekten alan odaklı. Başta o tür sorguları yazmanız gerekmese, korkunç derecede iç içe geçmiş sorgulardan ve bunun doğurduğu SQL sözdizimi acısından bu kadar şikâyet etmezdiniz. Tuple’ları ve ilişkileri işin genelde konuşulduğu biçime hizaladığınızda, zamanla bunlarla daha az boğuşursunuz. Şemayı en baştan refactor edemediğiniz durumlar çoktur; ama kötü şemanın etrafına kopyalar veya view’lar koyup yeni geliştirme ve refactoring hedefi haline getirebilirsiniz.
Elbette SQL’in kusurları var; test edilebilirlik gibi ciddi olanları da var. Yine de nihayetinde tüm programlamanın böyle olmasını isterdim. İçeride nasıl yapılacağına bilgisayar karar versin, insan mantığa odaklansın.
Bir adım daha ileri gitmek için Prolog’u kabaca okumaya çalıştım ama şimdilik başaramadım. Amaçlarımdan biri de SQL’e fazla hapsolmamak için bir kısmını unutmaktı. Belki programlamanın geleceği SQL ile Prolog arasında bir yerdedir.
Yalnızca küme işlemleri açısından düşünürseniz 5 milisaniye yerine 5 dakika süren sorgular üretmek kolay. Kafadaki süreç neredeyse her zaman “hangi tablodan başlamalı, hangi satırları hangi sırayla görmeli, neyle hangi koşulla join etmeli, nasıl aggregate etmeli” şeklinde ilerliyor. Küme işlemlerinden çok döngüler ve aggregation üzerine kurulu bir zihinsel modele yakın düşünüyorsunuz.
Pek çok kişi alakasız yerlere atlıyor ama yazılım mühendisliğinin büyük kısmı doğru veriyi doğru biçime koyup güvenilir şekilde taşımaktır.
Yakın zamanda karmaşık bir dağıtık codebase’i büyük ölçüde refactor ettim; gerçek “iş” sayılabilecek kısım neredeyse yalnızca şema yeniden tasarımıydı. Geri kalanı uzun süre kod yazmaktı ama aslında uygulamaya daha yakındı.
SQL dışında da şema tanımlama yolları var; ancak gerçek sistem mühendisliğini öğrenmek için SQL mükemmel bir yöntem.
Çok fazla SQL kullanıyorum ve stream processing uygulamalarındaki iş mantığının önemli bir bölümünü SQL ile uyguluyorum. Özellikle veriyi hesaplamaya taşımak yerine hesaplamayı verinin yanına getirme yaklaşımını gerçekten seviyorum.
Ancak bu fikri sevmeyen geliştiricilerle de sık sık karşılaşıyorum. Muazzam I/O maliyetini göze alıp tüm veriyi backend’e taşımak, ardından hesaplamayı “gerçek” bir programlama dilinde ifade etmek istiyorlar.
SQL kavramı güzel, ama sorun SQL dili diye düşünüyorum. Çok fazla hantal yanı var; yaklaşık 40 yıldır rekabet görmediği düşünülürse bu şaşırtıcı değil. Kafadaki program modeli iyi, ama zarafeti görmek için sözdiziminin ötesine, gerçekten kullandığınız programa bakmanız gerekiyor.
Bence ihtiyaç duyulan şey, mevcut veritabanlarını (Postgres, MSSQL) hedefleyen ve SQL lehçelerine derlenen düzgün bir programlama dili. Adaylar var gibi görünüyor; ama veri değiştirmeye izin vermeyen PreQL gibi belirli alanlara sıkışmışlar ya da başka veritabanlarıyla birleşik durumdalar.
Kendim yapmak istiyorum ama çok fazla iş var; benimsenene kadar uzun, çok uzun bir yol var, başarı garantisi yok ve aklıma gelen bir gelir modeli de yok.
Popüler backend dilleri büyük şirketler tarafından yapıldı; ama SQL ile kod yazmak, daha iyi bir dil çıkana kadar küçümseniyor, daha popüler hale gelene kadar da daha iyi bir dil çıkmıyor gibi görünen bir çıkmaz içinde.
Common Table Expression’lar ve pencere fonksiyonları büyük fark yarattı; özellikle pencere fonksiyonları insanın kafasını biraz karıştırsa da zor işleri biraz daha kolaylaştırıyor.
BigQuery kullanıyorum; struct ve array desteği var, daha yeni array’leri gruplayabilir hale geldi ama hâlâ eşitlik testi gibi şeyler yok.
BigQuery, aggregate kullanıcı tanımlı fonksiyonlar,
ANY TYPEparametreleri kullanan polimorfik kullanıcı tanımlı fonksiyonlar gibi sözdizimsel şekerleri yavaş yavaş ekliyor. Yeniden kullanılabilir mantığı temiz fonksiyonlara daha çok koyar hale geliyorsunuz; ama kişisel olarak geçici fonksiyonların Common Table Expression’lar gibi bildirilip kapsamlandırılmasını, böylece DBT gibi her şeyi tek bir ifadeye koymak isteyen araçlarla daha iyi entegre olmasını isterim.Üretkenliği en çok artıracak tek özelliği seçecek olsam,
JOIN USINGiçinde null davranışını belirleyebilme olurdu. Join’defoo.bar IS NOT DISTINCT FROM bar.barifadesini açıp yazmak sezgisel değil ve çirkin.USING (bar RESPECT NULLS)gibi bir şey çok daha iyi olurdu.Buna karşılık, küçük servislerin her birinin kendi veritabanına sahip olduğu ve bunların yalnızca yarısının ilişkisel veritabanı olduğu mikroservis tarzı yapılarda, veritabanının içine karmaşık kodu daha az koymak istiyorlar. Çünkü tekil instance veya cluster’dan sık sık taşınıyorlar; yanlarında çoğunlukla nispeten basit veri dump’ları götürüyorlar ya da Theseus’un gemisi gibi yeni replikalar ekliyorlar.
Bunu saf SQL ile yapmış olmaları gerçekten etkileyici, ama asıl çatlak mühendis enerjisinin işareti bana 10 yıldır ayakta duran Blogspot sitesi gibi geliyor
Tam olarak açıklaması zor ama güçlü bir “niş bir alanda usta” hissi veriyor. Yazarları tanımasanız bile, “database architects” adlı bir Blogspot sitesini 10 yıl boyunca sürdüren birkaç kişi, doğru toplulukta muhtemelen ayrıca tanıtılmaya ihtiyaç duymaz
Bu arada birkaç gün boyunca Advent of Code’u EdgeQL ile denedim ve oldukça ilginç bir deneyimdi
Birkaç tweet attım; sanırım bunu bir blog yazısına dönüştürmem gerekiyor
https://x.com/1st1/status/1864069589245858083
SQL ile karşılaştırma: https://x.com/1st1/status/1864412869108092997
Tam anlamıyla korkunç. Yine de iyi iş çıkarmışlar
Bilmeyenler için ekleyeyim: Yazar, dünyanın en iyi veritabanı araştırmacılarından biri