2 puan yazan GN⁺ 2025-01-03 | 1 yorum | WhatsApp'ta paylaş
  • 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

 
GN⁺ 2025-01-03
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.

    • Thomas, dünyanın en iyi veritabanı sistemleri araştırmacılarından biri ve gerçekten muazzam biri.
  • 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ı.

    • Veritabanlarıyla çok uğraştım ve türlü türlü şey gördüm ama ne yaptığınızı biliyorsanız sanıldığı kadar kötü değil. Çoğu ilişkisel veritabanı yönetim sistemi özyinelemeli ortak tablo ifadelerini destekliyor; biraz sadistik bir sözdizimiyle Prolog yazmak gibi.
      Advent of Code gibi problemlerde muhtemelen en zor kısım girdiyi ayrıştırmak olur.
    • Bu yazının GitHub deposundaki çözümler de Taco Bell’in yeni tavuk nugget’ları kadar şaşırtıcı.
    • Taco Bell’de katlanması zor olan şey sahte nacho peyniri. Hard taco’daki sıradan rendelenmiş peynir en iyisi olmasa da fena değil; ama içine Velveeta girince onu zorla yutmak için epey ciddi bir özdenetim gerekiyor.
      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.
    • İnsan yaratıcılığına neden utanç ve arzuyla tepki verildiğini anlamıyorum. Bunun sizden kaynaklanan bir mesele mi yoksa Taco Bell’e özgü tuhaf bir durum mu olduğu da belirsiz.
      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.

    • Stajyerken, matematik doktoralı birinin yazdığı bir stored procedure’ün performansını optimize etme gibi “eğlenceli” bir iş verilmişti. Yazdırınca 6 sayfadan uzundu, çalışması 30 dakikadan fazla sürüyordu, faturalama sisteminde kullanılıyordu ve testi yoktu.
      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.
    • Ancak ve ancak yeterince çok SQL’e hâkim kişi olduğunda büyük SQL karmaşıklığı barındırmanın iyi bir yolu olabilir. Kötü SQL yazmak çok kolay; yüzlerce procedure, view ve fonksiyona dağılmış binlerce satır kötü SQL’i çözmek ise zordur.
    • Büyük SQL’in karmaşıklığı barındırmada iyi olduğu hissini anlıyorum ama büyük SQL sorgularını debug etmek çok opak olabiliyor. pl/pgsql gibi şeyler yardımcı olsa da bu kez giderek genel amaçlı bir programlama diline benzemeye başlıyor.
    • İlk bakışta delilik gibi görünüyor; üzerinde düşünmeye devam edince de karmaşıklığı SQL’in içine koymak istemek hâlâ delilik gibi görünüyor.
      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...

    • Şu an telefondayım, açamıyorum; Google Apps Script kullanıp kullanmadığını merak ediyorum. Kullanıyorsa ekstra güç elde etmenin bir yolu olabilir.
  • 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.

    • Yıllar geçtikçe daha fazla sorumluluğu ilişkisel veritabanı yönetim sistemine itiyorum. Artık çoğu şeye ETL, SQL, şema açısından bakıyorum. Teknolojiyi işe uygulamaya dair neredeyse tüm konuşmalar bu terimlerle ifade edilebiliyordu.
      Ş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.
    • Uzun süre SQL kullandıktan sonra bir adım geri çekilip düşününce güzelliğini görüyorsunuz. “Bir dakika, az önce yaptığım şey sadece saf mantıktı. Kütüphane bağımlılığı çözme yok, eşzamanlılık sorunu yok, değişebilirlik sorunu yok; sadece mantık” hissi.
      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.
    • Sadece küme işlemleriyle düşünebilmek güzel olurdu; ama pratikte hızlı sorgular yazmak ve hangi indekslerin gerektiğini bilmek için hâlâ imperative/yinelemeli düşünme gerekiyor.
      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.
    • İyi veritabanı şema tasarımının teorik, pratik ve teknik unsurlarını bütünüyle kavramak, sistem tasarımını anlayıp anlamadığınızın en gerçek sınavıdır.
      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.
    • SQL’i, orijinal makaleyi okuyup küme perspektifinden açıkladıktan sonra gerçekten yerine oturttum.
  • Ç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.

    • SQL’de çok doğru olan pek çok şey var; ama kenarlardaki bazı kısımlar kaba.
      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 TYPE parametreleri 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 USING içinde null davranışını belirleyebilme olurdu. Join’de foo.bar IS NOT DISTINCT FROM bar.bar ifadesini açıp yazmak sezgisel değil ve çirkin. USING (bar RESPECT NULLS) gibi bir şey çok daha iyi olurdu.
    • Tam olarak ifade etmek zor ama birçok kişi bunu iki çalışma modu gibi görüyor sanki. Çözüm ne kadar monolitik, enterprise tarzı ve özel bir veritabanı yönetim sistemine yakınsa, indeksler ve birkaç trigger’ın ötesindeki karmaşıklığı da veritabanı tarafına koyma eğilimi o kadar artıyor.
      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.
    • PRQL harika. Benzer bir rakibi daha var ama adı şu an aklıma gelmiyor.
  • 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

    • Thomas Neumann’ın Thomas Neumann’lık yapması işte