- SQLite’in JSON özellikleri kullanılarak ham JSON belgelerini olduğu gibi saklayıp, gerekli alanları sanal üretilmiş sütunlar (virtual generated columns) olarak çıkarıp indeksleme yaklaşımı tanıtılıyor
json_extract işleviyle JSON içindeki veriler sütunmuş gibi ele alınabiliyor ve sorgular B-tree indeks hızıyla çalıştırılabiliyor
- Yeni sorgu desenleri gerektiğinde veri migrasyonu olmadan sütun ve indeks eklenerek genişletilebiliyor
- Bu yaklaşım, şemasız verinin esnekliğini ve ilişkisel veritabanının performansını aynı anda sağlıyor
- SQLite kullanan geliştiriciler için sade yapı ve yüksek performans sunan pratik bir desen olarak vurgulanıyor
SQLite ve JSON özelliklerinin birleşimi
- SQLite, JSON işlevleri ve operatörlerini destekler; bu sayede JSON verisi doğrudan saklanabilir ve işlenebilir
- JSON belgesini tek bir sütunda olduğu gibi tutup, yalnızca gereken bilgileri sanal sütunlar olarak çıkarabilirsiniz
- Bu yaklaşım, şema tanımı olmadan veriyi esnek biçimde kullanmayı sağlar
- DB Pro ekibi son birkaç ayda SQLite’i yoğun biçimde kullanarak bu özellikleri gerçek iş yüklerinde doğruladı
- SQLite, doğru yapılandırıldığında prodüksiyon ortamında da güvenle kullanılabilir
Sanal üretilmiş sütunlar (Generated Columns)
json_extract kullanılarak JSON içindeki belirli değerler sanal üretilmiş sütunlar olarak tanımlanabilir
- Bu sütunlar gerçek veriyi saklamaz; sorgu anında hesaplanır ve hemen kullanılabilir
- Ayrı bir backfill süreci ya da veri kopyalama gerekmez
- Örneğin JSON verisinden belirli alanları çıkarıp onları normal sütunlar gibi ele alan bir yapı kurulabilir
İndeks ekleme ve performans artışı
- Sanal sütunlara indeks eklendiğinde, JSON verisi de normal sütunlar gibi B-tree indeks hızıyla aranabilir
- İndeks eklenmiş sanal sütunlar, ilişkisel veritabanı sütunlarıyla aynı performansı sunar
- Bu yaklaşım, JSON verisinin boyutu büyük olsa bile hızlı aramayı mümkün kılar
Yeni sorgu desenleri ekleme
- Daha sonra yeni bir alan üzerinden arama gereksinimi doğarsa, yalnızca yeni bir sanal sütun ve indeks eklemek yeterlidir
- Örnek:
user_id alanını çıkarıp buna indeks oluşturmak
- Mevcut veri satırlarını değiştirmek veya migrasyon yapmak gerekmez
- Böylece veri yapısını değiştirmeden anında sorgu genişletilebilirliği elde edilir
Desenin avantajları ve önemi
- Bu desen, şemasız JSON saklamanın esnekliğini ve ilişkisel veritabanı indeks performansını birleştirir
- İlk tasarım aşamasında indeksleme stratejisini önceden belirlemek gerekmez
- Gerektiği anda sütunlar ve indeksler eklenerek optimizasyon yapılabilir
- SQLite kullanan geliştiriciler için basit ama güçlü bir veri işleme yöntemi olarak sunuluyor
- DB Pro, gelecekte SQLite’in farklı özelliklerini ele alan ek yazılar yayımlayacağını belirtiyor
2 yorum
Hacker News yorumları
JSON belgeleri doğrudan serileştirilmiş bir B-tree olarak kodlanabilir
Bu sayede iç alanlara indekslenmiş hızlarda doğrudan erişilebilir ve belgenin kendisi zaten indekslenmiş olduğundan ayrıştırma gerekmez
Bu formata Lite³ deniyor. Üzerinde bizzat çalıştığım bir proje
GitHub bağlantısı
Lite³'ün
lite3_val_bytesile ikili veri desteği sunması özellikle hoşuma gittiJSONB, dizi uzunluklarını ve ofsetleri birlikte kodlayarak sıkıştırma verimliliği ile hız arasında denge kurabiliyor
Lite³ yerinde güncelleme yapabiliyor ama hassas verilerin kalmaması için düzenli olarak “vacuum” gerekiyor
JSONB yeniden kodlama olmadan güncellenmesi zor bir yapı ama Lite³ yalnızca yapıyı dolaşarak kolayca toparlanabiliyor
Sıkıştırılabilirlik tarafında JSONB daha iyi olabilir ama Lite³'ün tasarımı bence çok zekice bir yaklaşım
Ben de bir ASN.1 derleyicisinin bakımını yapıyorum, bu yüzden böyle serileştirme formatlarına ilgim var. Lite³ bana yeni fikirler verdi
SQLite'ı gerçekten çok seviyorum ama analitik için daha sık DuckDB kullanıyorum
DuckDB, SQLite gibi tek dosya kullanırken büyük veri kümelerini de son derece hızlı işliyor
M2 MacBook'ta 20 milyon kaydı işlerken bile çok hızlı
Örneğin şu sorguyla JSON dosyaları doğrudan okunabiliyor
Ayrıca JSON tipinde kolonlar yükleyip Postgres tarzı
col->>'$.key'söz dizimini de kullanabiliyorsunuzYine de SQLite ile karşılaştırmak biraz haksızlık. SQLite sistem kurmak için, DuckDB ise analitik için daha uygun
Birden fazla platforma dağıtım yaparken DuckDB biraz zahmetli olabiliyor
JSON performansı için Generated Column kullanmanın yaygın bir yöntem olduğunu sanıyordum
Postgres'te de JSON kolonundaki anahtarları yabancı anahtar olarak korumak için bunu kullanmıştım. Biraz 'lanetli' bir yöntem ama işe yarıyordu
Mesela İlgili blog yazısı
JSON şeması değişirse ayrıştırma ya da migrasyon başarısız olabilir
Bu tekniği yakın zamanda Claude Code'un önerdiği bir optimizasyon örneği sayesinde öğrendim
SQLite'ın yeni özelliklerini bilmediğim için gözden kaçırmışım ama performans artışı oldukça büyüktü
Buradan çıkarılacak ders, aşina olduğunuz araçlarda bile belgeleri ara ara yeniden okumanın faydalı olduğudur
2023'te HN'de bambax'ın yorumunu görüp bu blog yazısını yazmaya karar vermiştim
Orijinal yorum bağlantısı
JSON'u doğrudan projekte etmeden de indeks oluşturabilirsiniz ama hesaplanmış kolon (computed column) sorguları sadeleştiriyor
MS-SQL 2025(v17) öncesinde JSON desteği sınırlı olduğu için bu yöntem gerekliydi
HN'de makaleyi açtım ve kendi yorumumun alıntılandığını, üstelik bunun yazının konusu olduğunu görünce tuhaf bir deneyim yaşadım
“Teşekkürler, bambax!” ifadesini görünce gülümsedim. SQLite gerçekten harika bir araç
İlginç ama SQLite'ın "Index On Expression" özelliği de kullanılabilir değil mi?
Örneğin
CREATE INDEX idx_events_type ON events(json_extract(data, '$.type'))Ancak JSON path söz dizimi azıcık bile farklı olursa indeks kullanılmayabilir. Buna karşılık Virtual Generated Column her zaman indeksi garanti ediyor
Örnek: recordlite projesi
Mesela
json_extract(data, "$.type")iledata -> '$.type'farklı kabul ediliyorYani WHERE koşulundaki ifade değişirse indeks işe yaramaz hale geliyor
Geliştiricilerin, tutarlı bir şema varken tüm veriyi JSON(B) kolonuna koyma alışkanlığından kaçınmasını isterdim
İndeks kurmak, kısıtları yönetmek zorlaşıyor ve gerçek kullanımda ek yük artıyor
Mesela Haskell+TypeScript ortamında karmaşık iç içe yapıları JSON olarak serileştirmek çok daha pratik
Örneğin birden fazla ödeme işlemcisinin sonuçlarını tek tabloda saklamak ya da bir ilan sitesinde kategoriye göre değişen özellikleri yönetmek için
C# ya da JS/TS'de tür doğrulama araçlarıyla (Zod, OpenAPI vb.) birlikte kullanıldığında yönetimi kolaylaşıyor
Sonuçta mesele, bakım kolaylığı ile performans arasındaki denge. Bu yazının ana fikri de JSON üzerinde kolayca indeks kurulabilmesi
Okuma performansı da indekslerle yeterince telafi edilebiliyor
Örneğin bir ürün fiyatlandırma sisteminde müşteriye özel sıra dışı indirim kurallarını JSON ile ifade etmek çok daha esnek
JSON yerine XML kullanırsanız, bu aslında 90'lar ve 2000'lerdeki belge tabanlı veritabanı (document store) modeliyle aynı şey olur
Ekleme ve güncellemede ayrıştırma yapılıyor, sorgu sırasında ise yalnızca indekse erişiliyordu
SQLite'ın bunu yerleşik olarak sunması gerçekten çok ilginç