- OpenDocument Presentation (ODP), ZIP arşivi yerine SQLite konteyneri içine konursa belge kaydetme, başlatma ve kurtarma yöntemleri daha güvenli ve hızlı tasarlanabilir
- Günümüzde ODP, XML ve görsel dosyalarını ZIP arşivi içinde paketleyen bir yapıya sahiptir; 49 slaytlık örnek sunum dosyası
content.xml, styles.xml, meta.xml, settings.xml ve görseller dahil toplam 78 öğeden oluşur
- ZIP tabanlı yapıda küçük bir değişiklikte bile tüm arşivi baştan yazmak kolay olduğundan artımlı güncelleme zordur; bu da File/Save gecikmesine ve SSD yazma miktarının artmasına yol açar
- SQLite’a geçilirse dosyalar tablo satırları olarak saklanabilir; dahası slayt bazında içerik ve sürüm ayrılarak yalnızca ilk slaydı okuma veya yalnızca değişen slaytları kaydetme yöntemi mümkün olur
- Bu, OpenDocument’ın kendisini eleştiren veya değiştirmeyi öneren bir metin değil; SQLite’ın uygulama dosya formatlarında atomik kaydetme, erişilebilirlik, sürüm yönetimi ve kurtarma özelliklerini kolaylaştırabildiğini gösteren bir örnektir
Düşünce deneyinin kapsamı ve konusu
- Konu, OpenDocument içinde sunum belgesi formatı olan ODP (OpenDocument Presentation)’dir
- Amaç OpenDocument’ı fiilen değiştirmek değil, gelecekteki dosya formatı tasarımlarında SQLite’ı konteyner olarak kullanma yaklaşımını değerlendirmektir
- Beklenen faydalar daha küçük belgeler, daha hızlı File/Save, daha hızlı başlatma, daha az bellek kullanımı, belge sürüm yönetimi ve daha iyi kullanıcı deneyimidir
Mevcut ODP dosya yapısı
- ODP dosyası, XML dosyaları ve görsel kaynaklar içeren bir ZIP arşividir
- Örnek olarak, 2014 SouthEast LinuxFest’teki SQLite konulu 49 slaytlık sunum dosyası
zip -l çıktısında toplam 78 öğeye sahiptir
content.xml, styles.xml, meta.xml, settings.xml adlı dört XML dosyası slayt düzenini, metin içeriğini ve stilleri tanımlar
- Sunum dosyasında tam ekran fotoğraflardan küçük ikonlara kadar 62 görsel ayrı dosyalar halinde saklanır
mimetype dosyasında tek satır olarak application/vnd.oasis.opendocument.presentation bulunur
- OpenDocument kelime işlemci ve elektronik tablo dosyaları da benzer yapıya sahiptir, ancak analiz konusu ODP’dir
ZIP tabanlı ODP’nin sınırlamaları
- ZIP arşivi, bir kez yazılıp birçok kez okunmaya optimize edilmiş bir anahtar/değer veritabanına yakındır ve az sayıda anahtarın büyük BLOB değerleri tuttuğu yapılara uygundur
- Tek tek öğeleri güncellemek zor olduğundan kullanıcı
File/Save seçtiğinde genellikle tüm ZIP arşivi yeniden oluşturulur
- Güç kesintisi veya çökme sırasında belgenin tamamını bozmadan tekil öğeleri güncellemek mümkündür, ancak yeterince zor olduğundan pratikte neredeyse hiç kullanılmaz
- 50 MB’lık bir sunum dosyasında yalnızca tek bir karakter değişse bile 50 MB’ın tamamının yeniden yazıldığı bir durum oluşur
- Başlatma süresi yavaşlayabilir
- ODP, tüm slayt içeriğini
content.xml adlı büyük bir XML dosyasında saklar
- LibreOffice ilk slaydı göstermek için bu dosyanın tamamını okuyup ayrıştırır
- Görünüşe göre görsellerin tamamı da belleğe okunur; bunun sonucunda dosyaya çift tıklandığında ilk slayt yerine bir ilerleme çubuğu görünür
- Bellek kullanımı artar
- ZIP yapısı, başlangıçta tüm belgeyi belleğe okuyan, düzenlemeyi bellekte yapan ve kaydetme sırasında tüm belgeyi diske yazan uygulama tarzını teşvik eder
- 50 MB’lık bir sunum dosyası 200 MB’tan fazla RAM kullanabilir
- Birden fazla sunum dosyası aynı anda açıkken tarayıcı ve masaüstü uygulamaları da birlikte kullanılırsa swapping gerçekleşebilir
- Çökme kurtarma zahmetli hale gelir
- OpenOffice türevleri çökmelere karşı bellekteki belgeyi düzenli aralıklarla yedekler
- Yedekleme sırasında uygulama birkaç saniyeliğine donabilir ve yeniden başlatma sonrasında ayrı bir kurtarma iletişim kutusundan geçmek gerekir
- İçeriğe erişilebilirlik düşüktür
- ZIP araçlarıyla görseller çıkarılabilir, ancak slayt metnini genel araçlarla çıkarmak veya düzenlemek zordur
- Örnek dosyadaki
content.xml dosyasının ilk satırı XML bildirimi, ikinci satırı ise tek satır halinde 211.792 karakterlik XML içerir
İlk iyileştirme: ZIP’i SQLite ile değiştirmek
- İlk adım, ZIP öğelerini SQLite tablo satırlarına dönüştüren basit bir yapıdır
CREATE TABLE OpenDocTree(
filename TEXT PRIMARY KEY,
filesize BIGINT,
content BLOB
);
- Bu aşamada dosya formatının geri kalan yapısı değiştirilmez
- Hâlâ bir “dosya yığını” yapısıdır, ancak her dosya ZIP girdisi değil SQLite veritabanındaki bir satır olur
- NeoOffice’in oluşturduğu
self2014.odp ile aynı içeriğin SQLAR aracıyla yeniden paketlenmiş SQLite dosyası boyut karşılaştırması şöyledir
self2014.odp: 10.514.994 bayt
self2014.sqlar: 10.464.256 bayt
- Komut satırındaki
zip ile yeniden sıkıştırılmış zip.odp: 10.416.644 bayt
- SQLite dosyası, NeoOffice’in ürettiği ODP’den yaklaşık %0,5 daha küçüktü
- Komut satırındaki
zip ile iyi sıkıştırılmış ZIP dosyası ise SQLite’tan tekrar yaklaşık %0,5 daha küçüktü
- SQLite veritabanı, boyut açısından ZIP arşiviyle rekabet edebilir
- SQLite atomik yazma sunduğu için, çökme veya güç kaybı sırasında bile belgeyi bozma riski olmadan artımlı değişiklikler kaydedilebilir
content.xml dosyasının tamamını yeniden yazma sınırlaması devam eder
- Yine de diğer 77 dosya olduğu gibi bırakılabildiğinden File/Save hızlanır ve SSD’ye yazılan veri miktarı azalır
İkinci iyileştirme: İçeriği küçük parçalara bölmek
- SQLite, büyük blokların yanı sıra çok sayıda küçük parçayı da verimli biçimde saklayabildiğinden slayt bazlı bir içerik tablosu kullanılabilir
CREATE TABLE slide(
pageNumber INTEGER,
slideContent TEXT
);
CREATE INDEX slide_pgnum ON slide(pageNumber);
- İlk ekranı gösterirken uygulamanın yalnızca ilk slaydı okuması yeterlidir
SELECT slideContent FROM slide WHERE pageNumber=1;
- Bu yapıda yalnızca ilk slayt içeriği hızlıca alınıp ayrıştırılarak gösterilebilir; başlangıçta tüm
content.xml dosyasını okumaya gerek kalmaz
- Uygulama seçenekleri de artar
- İlk slayt gösterildikten sonra kalan sayfalar arka plan iş parçacığında okunabilir
- Bellekte yalnızca mevcut slayt tutulabilir
- Hızlı geçiş için mevcut slayt ve sonraki slayt bellekte tutulabilir
- Kaydetme de yalnızca değişen sayfaları yeniden yazmayı gerektirdiğinden File/Save daha hızlı hale gelir
- Kısa metin parçalarında sıkıştırma verimliliği düşebilir ve belge boyutu artabilir
- Ancak belge alanının büyük kısmını görseller kapladığından, metin sıkıştırma verimindeki azalma kullanıcı deneyimi iyileşmesine kıyasla küçük bir maliyet olarak görülebilir
Üçüncü iyileştirme: Sürüm yönetimi
- Slaytlar tekil nesneler olarak saklandığında aynı belge içinde sürüm geçmişi tutulabilir
CREATE TABLE slide(
slideId INTEGER PRIMARY KEY,
derivedFrom INTEGER REFERENCES slide,
content TEXT
);
CREATE TABLE version(
versionId INTEGER PRIMARY KEY,
priorVersion INTEGER REFERENCES version,
checkinTime DATETIME,
comment TEXT,
manifest TEXT
);
- Her slayt sayfa numarası yerine benzersiz bir
slideId değerine sahip olur; sıra, version tablosundaki manifest içinde saklanan slideId listesiyle belirlenir
- Başlangıçta uygulama önce gösterilecek sürümü seçer ve genellikle en yeni sürümü alabilir
SELECT manifest, versionId FROM version ORDER BY versionId DESC LIMIT 1;
checkinTime temelinde en yeni sürümü getiren sorgu da mümkündür
SELECT manifest, versionId, max(checkinTime) FROM version;
- SQLite’ta yukarıdaki
max(checkinTime) sorgusu tanımlı bir sonuç döndürür; ancak birçok başka SQL veritabanında tanımsız bir sonuç döndürebilir veya hata verebilir
- Kullanıcı
File/Save yaptığında yalnızca değiştirilmiş slaytlar slide tablosuna yeni satırlar olarak eklenebilir ve değiştirilmiş manifest değerine sahip yeni bir version satırı oluşturulabilir
version tablosu check-in zamanını, kullanıcı yorumunu ve üst sürümü kaydederek değişiklik geçmişini korur
- Aynı belge içinde birden fazla sunum saklamak da mümkündür
- Ayrı bir yedekleme dosyası yerine özel bir
pending sürümü kullanılırsa kaydedilmemiş değişiklikler sık sık ve sessizce kaydedilebilir
- Tüm belge yerine yalnızca değişiklikler yazılacağı için birkaç MB değil birkaç KB yazan bir işlem olur
- Kaydetme süresi saniyeler değil milisaniyeler düzeyinde olabilir
- Çökme sonrası yeniden başlatılsa bile kullanıcının çalışmasının büyük kısmı veya neredeyse tamamı korunabilir
- Kullanıcı kaydedilmemiş değişiklikleri atmak isterse önceki sürüme dönebilir
SQLite dosya formatında mümkün olan diğer özellikler
- SQLite konteyneri, yalnızca üç tabloyla bile uygulama dosya formatına önemli özellikler ekleyebilir
- Ek olarak şema, indeksler, tetikleyiciler, görünümler ve kısıtlar kullanılarak performans, kullanım kolaylığı ve tutarlılık artırılabilir
- Genişletme fikirleri şunlardır
- Veritabanı tablolarında otomatik undo/redo yığını saklanarak önceki düzenleme oturumlarına kadar geri alma mümkün olur
- Slayt destesi veya birden çok slayt destesine tam metin arama işlevi eklenir
settings.xml SQL tablolarına ayrıştırılarak başka uygulamalarda daha kolay görüntülenip düzenlenebilir
- Her slaydın sunumcu notları ayrı bir tabloya ayrılarak üçüncü taraf uygulamalar veya script’ler tarafından kolayca erişilebilir hale gelir
- Basit doğrusal slayt sırasının ötesinde, dinleyici tepkisine göre farklı yollar ve yan akışlar içeren sunum yapıları desteklenir
SQLite’a yönelik yaygın çekinceler ve yanıtlar
- Kurumsal SQL veritabanı deneyimi nedeniyle SQLite’ı uygulama dosya formatı olarak kullanmaya karşı çekince duyulabilir
- Birçok kurumsal veritabanı büyük string veya BLOB değerlerini veritabanına koymak yerine ayrı dosyalar olarak saklamayı önerir, ancak SQLite farklıdır
- Tüm SQL şemalarının üçüncü normal formda (3NF) olması ve yalnızca küçük ilkel tipler saklaması gerektiği düşüncesi de kısıtlayıcı olabilir
- İlişkisel teori önemlidir, ancak gerçek dosya formatlarında XML veya JSON gibi karmaşık bilgileri metin alanlarında saklamak da kabul edilebilir bir seçimdir
Uygulama dosya formatı olarak SQLite
- SQLite veritabanı dosyası, aynı bilgileri içeren ZIP arşiviyle neredeyse aynı boyuttadır ve bazı durumlarda daha küçük olabilir
- Atomik güncellemeler sayesinde küçük değişiklikler belgeye güvenli biçimde kaydedilerek disk I/O’su azaltılabilir ve File/Save performansı artırılabilir
- Uygulama yalnızca ilk ekran için gereken içeriği okuyarak başlatma süresini kısaltabilir
- Yalnızca mevcut görüntüyle ilgili içerik bellekte tutulup kalanı diskte bırakılabildiğinden bellek kullanımı ciddi ölçüde düşürülebilir
- SQL şeması, ZIP gibi anahtar/değer yapılarından daha doğrudan ve yalın biçimde bilgi ifade edebilir
- Üçüncü taraf uygulama ve script’lerin erişilebilirliği artar
- Yerleşik belge sürüm yönetimi ve çökme sonrası çalışma kurtarma gibi gelişmiş özelliklerin uygulanması kolaylaşır
- OpenDocument zaten yerleşik ve iyi tasarlanmış bir formattır; SQLite, OpenDocument’tan sonra çıktığı için mevcut tercihi eleştiren bir içerik değildir
- Application File Format belgesi, SQLite’ı uygulama dosya formatı olarak kullanmaya yönelik ek fikirler sunar
1 yorum
Hacker News görüşleri
SQLite'ı dosya biçimi olarak kullanan bir uygulama geliştiriyorum
Kullanıcının belgeyi düzenleyip yalnızca kaydettiğinde dosyanın değiştiği alışılmış akışı korumak istediğim için, dosya açılırken onu
:memory:veritabanına kopyalıyorum: https://www.sqlite.org/inmemorydb.htmlKullanıcı istediği gibi işlem yapıyor, uygulama da ayrı bir belge modeli olmadan değişiklikleri doğrudan veritabanı biçimine yansıtıyor. Kaydederken
VACUUMile tekrar veritabanı dosyasına yazarak hallediyorum: https://www.sqlite.org/lang_vacuum.htmlMakul boyuttaki dosyalarda iyi çalışıyor; benim uygulamamda dosyalar her zaman bu aralıkta kalıyor
Bunun yerine doğrudan veritabanına otomatik kaydetmek ve kaydet düğmesini kaldırmak daha iyi. Çakışmalara dayanıklı olur, tek veritabanı olduğu için kod ve hata sayısı azalır; SQLite yazmaları ya başarılı olur ya başarısız, ara bir durum yoktur. Buna karşılık, belgede alıntılandığı gibi
VACUUM INTO, beklenmedik kapanma veya güç kaybı durumunda çıktı veritabanını eksik ya da bozuk bırakabilirSQLite'ı baştan tasarlandığı şekilde kullanırsanız, SQLite'ın ömrü boyunca bu kısmı düşünmek zorunda kalmazsınız
Her işlemden sonra geçici bir konuma, örneğin XDG dizinlerine göre
~/.local/share/application/yourappgibi bir yere kaydetmek ve kullanıcı kaydet'e bastığında dosyayı istediği konuma kopyalamak çok daha iyi. Güç kaybından sonra uygulamayı yeniden açsanız bile neredeyse aynı noktadan kurtarılır; en fazla son birkaç saniyeyi kaybedersinizKullanıcı kaydettiğinde checkpoint çalıştırıp WAL içeriğini ana veritabanına birleştirmek yeterli olur
VACUUM, içeriği geçici bir veritabanı dosyasına kopyaladıktan sonra asıl dosyanın üzerine yazar; üzerine yazarken de normal bir transaction gibi rollback journal veya WAL kullanır. Bu yüzden asıl dosyanın yaklaşık iki katı kadar boş alana ihtiyaç duyarVACUUM INTO, geçici veritabanı yerineINTOile belirtilen dosyayı kullanır ve sonra asıl dosyanın üzerine geri kopyalama adımını atlar. Gerçekte kullanılanın güç kesintisine dayanıklıVACUUMmu, yoksa yazma sırasında güç kesintisine karşı hassas olan ve mevcut dosya adı kullanılırsa onu bozabilecek gibi görünenVACUUM INTOmu olduğu önemlidirSQLite'ın sorunu standartlaştırılmış bir dosya biçimi olmaması
İyi belgelenmiş ve yaygın biçimde anlaşılmış olsa da, bir SQLite dosyasının nasıl yorumlanacağını ISO standardı ayrıntılı biçimde tanımlamıyor. Alternatif implementasyonlar için de aynı durum geçerli
Zip ve XML'in API yüzeyi SQLite'a göre çok daha küçüktür. SQLite'ın API'si birkaç C fonksiyonunun ötesinde SQL dilinin kendisidir; SQL parser, sorgu optimizer, compiler, bytecode sanal makinesi, full-text search engine vb. bileşenleri veri bozulması olmadan uygulamak, bir XML parser yazmaktan çok daha büyük bir iştir
Birlikte çalışabilirliğin veya ISO standardizasyonunun önemli olmadığı alana özgü kapalı bir uygulamada SQLite iyi bir dosya biçimidir, ancak OpenOffice için bu tür endişelerin gerçekten var olduğunu anlıyorum
SQLite C kütüphanesi de public domain, kaynak kodu tamamen açık, dosya biçimiyle ilgileniyor ve belgelendirme düzeyi çoğu ISO standardından daha yüksek. Başlıca diller için binding'leri de neredeyse tamamen mevcut
SQLite dosyası içinde saklanacak bir OpenDocument biçiminin henüz oluşturulup belgelenmeyi beklemesi ayrı bir mesele. ISO standardı iyi bir şey, ama dosya biçimlerini ISO'nun tanımlamasını beklemek zorunda kalsaydık kullanabileceğimiz şeyler çok az olurdu
Bu, bir LibreOffice hesap tablosunu okumak için tüm hesap tablosu özelliklerini uygulamak zorunda olmamaya benzer. Gereken şey tabloları yeniden oluşturabilme yeteneğidir; ardından istediğiniz bilgileri seçtiğiniz dilde yazılmış imperative kodla dolaşarak elde edebilirsiniz
O kütüphaneyi yeniden uygulamak büyük iş olurdu, ama bu OpenDocument dosya biçimini kullanan kodu yeniden uygulamakla aynı türden bir iştir. Dosya biçiminin kendisi oldukça basittir
Uyumluluktan endişe ediliyorsa belge, MySQL gibi başka veritabanlarıyla da erişilebilir olacak şekilde yapılabilir
Audacity’nin SQLite’ı benimserse dosya kaydetme işlevinin büyük ölçüde iyileşeceğini sanmıştım, ama pratikte pek çok tuzak varmış
Linux’ta
/etc/fstabile oluşturulmuş, root’a ait ama herkesin yazabildiği bir NTFS bağlama noktasına yeni dosya olarak kaydedince izin hatası gibi nedenlerle başarısız oluyor; mevcut bir dosyaya kaydedince ise düzgün çalışıyorduBir projeyi düzenlediğiniz anda diskteki dosya değiştiriliyor; Audacity projesini Git’e ikili bir yığın olarak koyarsanız gereksiz Git farkları oluşuyor. Kaydetseniz bile eski ya da silinmiş veriler, proje penceresi kapanana kadar SQLite dosyasında kalıyor; commit’ten önce pencereyi kapatmazsanız depoya girebiliyor. Eskiden
.aup3dosyasına elleVACUUMyapmak gerektiğini hatırlıyorum, şimdi ise pencereyi kapatmak yeterli. Word 2003’ün Fast Save özelliğini andırıyorBirkaç yüz MB olması gereken proje birkaç GB’a çıktığında ve disk alanından tasarruf etmek gerektiğinde, basit tek kanallı işler için Mix and Render çözüm oluyordu. Sesi değiştirmiyordu ama kaydetme ve çıkış sırasında artık verileri temizleyebiliyordu
Bu SQLite’ın kendi sorunu değil, açıkça uygulama katmanı sorunu. Audacity 2’de geçici çalışma alanı kavramı var gibiydi; Audacity 3 ise
.aup3dosyasının kendisini çalışma alanı olarak kullanıyor gibi görünüyorAudacity 3 biçimine bakmıştım; eski
.aupdosyasına karşılık gelen proje verilerini tek satırlık bir tabloda XML olarak saklarken, metni olduğu gibi yazmayıp basit bir sözlük kodlayıcıyla kodlaması beni çok şaşırtmıştı. Birlikte çalışabilirliği ve denetlemeyi çok daha zorlaştırıyor, performansa da az da olsa zarar veriyor; alan tasarrufu ise yüzlerce MB’lık ses dosyalarında birkaç KB düzeyinde yuvarlama hatası kadar olurGit açısından fark ve birleştirmesi kolay bir metin biçimi kullanmak daha avantajlı. SQLite dump’ının bu açıdan ne kadar kolay olduğunu bilmiyorum
Önemliyse elle düzeltilebilir ama genelde dosyayı atınca tekrar çalışıyor
Güzel yazı. Yine de OpenDocument’ın Zip arşivi içindeki XML dosyaları kümesi olması hoşuma gidiyor
Belge biçimini bilen ağır bir kütüphane olmadan da elektronik tablo gibi belgeler oldukça kolay üretilebiliyor
Bir web servisi kullanıcısının tablo satırları olarak dışa aktardığı verileri birden fazla araçta kullanmak istediği durumlar oluyor. UTF-8 CSV açık, geleneksel ve kullanılabilir bir format; ama son kullanıcıya CSV sunmuş olan herkes, elektronik tablo uygulamalarında yaşanan tıkanmanın acısını bilir
Örnek bir elektronik tabloyu OpenDocument’ın ODS’i ve Microsoft’un XML canavarı OOXML’in XLSX’i olarak kaydettikten sonra XML biçiminin temelini anlamıştım. Zip arşivini yalnızca gerekli öğeler kalacak şekilde küçülttüm, içeriğin geleceği yerleri işaretledim ve istek geldiğinde yeni bir elektronik tablo dosyası ürettim. Artık aynı veriyi CSV, ODS, XLSX ve JSON olarak çıktılayabiliyorum
SQLite ile de yapılabilir ama biraz daha karmaşık olur ve geliştirme hızını düşürür. Bir ofis paketiyle şablon belge oluşturup kaydedilen dosyanın XML’inin içine dalabilmek niş ama güzel bir özellik
Özellikle
nl_NLgibi yerellerde Excel’in CSV dosyalarında sütun ayırıcısını noktalı virgül olarak sabit kodlanmış gibi davranması sorun. Çünkü Microsoft, Hollandalıların comma separated values dosyalarında virgül kullanmadığına kötü şöhretli bir şekilde karar vermişlocaleconv()->decimal_pointdeğerine bağlı. Değer,ise Excel hem CSV dosyalarında hem de formül ifade dilinde noktalı virgül kullanıyorEskiden Excel’de CSV/TXT açarken bunu ayarlamak mümkündü ve LibreOffice’te hâlâ mümkün, ama genel UI sadeleştirme sürecinde
Datamenüsünde/şerit sekmesinde bir yerlere taşındı. Yeni bir çalışma kitabı açıp doğru seçeneği bulmanız gerekiyor; zamandan kazanmak istiyorsanız LibreOffice kullanmak daha iyiBu kısım gerçekten şaşırtıcıydı. İç içe sorguya gerek olmamasına inanmak zor
SELECT manifest, versionId, max(checkinTime) FROM version;SQLite’ta
max(checkinTime)kullanan bu ikinci sorgunun gerçekten düzgün çalıştığı ve tanımlı bir cevap döndürdüğü söyleniyor. Diğer SQL veritabanı motorlarında tanımsız bir cevap döner ya da hata olur; ama SQLite, en büyükcheckinTimedeğerine sahip öğeninmanifestveversionIddeğerlerini döndürüyorBu durumda iç içe sorguya gerek yok;
checkinTime’a göre sıralayıp sonucu bire sınırlamak yeterli:select manifest, versionId, checkinTime from version order by checkinTime desc limit 1En azından SQLite ve PostgreSQL’de çalışır. Oracle’da
where rownum=1kullanmak gerektiği için iç içe sorgu gerekiyordu diye hatırlıyorumGROUP BY manifest, versionId ORDER BY 3 DESC LIMIT 1ifadesinin ya da en büyükcheckinTimedeğerini bulup ardından join yapan bir CTE’nin kısaltması gibi görülebilirAncak aynı en büyük
checkinTimedeğerine sahip birden fazla satır varsa rastlantısallık var ve bu bir ayağın altındaki silaha dönüşebilir; bu yüzden SQLite3’e özgü bu özelliği pek kullanmıyorum. Deterministik olarak en iyi satırı seçmek için yukarıdakine benzer açık bir yöntem gerekirPostgres’te
DISTINCT ONsorgusuyla benzer bir şey yapılabilir. SQL’de basit görünen ama bana en zor gelen işlerden biriydimanifestveversionId,max(checkinTime)değerine fonksiyonel olarak bağımlı değilÖrneğin aynı
checkinTimedeğerine sahip iki satır olabilir ve bu değer en büyük değer olabilirHem SQLite hem de XML dosyaları kullanan bir ürün çıkarmıştım
İyileştirdiğimiz noktalardan biri, az veri içeren bazı tabloları XML dosyalarına taşımaktı. Dosyalar küçük ve neredeyse hiç kullanılmadığı için veri erişim katmanı ve tanılama basitleşti; bunları birden çok satırlı, sekme girintili XML olarak oluşturduk
Ürünü tanılaması gereken teknik görevliye SQLite veritabanını açıp bakmasını söylemek büyük bir yük oluyordu. Ancak ürünün ana bölümlerinde SQLite, XML dosyalarından ezici biçimde daha iyiydi. Önceki sürüm XML dosyaları kullanıyordu; XML dosyalarında iyi bir artımlı güncelleme yöntemi olmadığı için ölçeklenebilirlik sorunları vardı
XML’in insan tarafından okunabilir format olma avantajı, ancak dosya küçük olduğunda ve şema tasarımı okunabilir XML’e uygun yapıldığında gerçekten işe yarıyor. Her seferinde tüm XML dosyasını yeniden yazma zorunluluğu ve özellikler arttıkça ortaya çıkan karmaşıklık, XML’in en büyük avantajını hızla aşındırıyor
Sıradan kullanıcıların ofis belgelerinin içini doğrudan kurcalaması yeterince nadir bir durum; bu yüzden SQLite okuyucu kullanmayı öğrenmek kabul edilebilir bir giriş engeli sayılır. Dosyanın ortasına rastgele yazma konusunda XML+Zip’in sınırları Moore yasasıyla bile aşılamaz
TEXTveyaBLOBalanlarının sıkıştırılıp sıkıştırılmadığını ya da çağıranın yazmadan önce BLOB’u sıkıştırmasının varsayılıp varsayılmadığını merak ediyorumODT, standartlaştırma düşünülerek tasarlanmıştı. Önceki format da çok benzerdi ama XHTML, SVG, CSS gibi mevcut standartlara büyük ölçüde dayanıyordu
Mevcut standartlara atıf yapılamazsa ODT şartnamesinin kendisi bir anda devasa hale gelirdi. Standardı güncelleme çabası da epey büyük görünüyor ve son birkaç yılda pek ilerleme olmadı
Gerçekçi olarak SQLite formatı bir seçenek olarak sunulabilir, ancak ofis belge formatları için gemi çoktan kalkmış gibi. Yine de SQLite şartnamesini resmî standart olarak düzenleme savı için iyi bir gerekçe oluşturuyor
ooo:rsidözniteliği nedeniyle yerel stillerin ve metin aralıklarının patlaması, seyrek olmayan elektronik tablolar, tablo stillendirmesinin tuhaf mekanizması gibi birkaç kusur dışında, bu tür belge verileri için çok iyi tasarlanmış bir işaretleme. Semantik işaretleme ile kullanıcının gerçekten yapmak istediği görsel ifade arasında iyi bir denge varBuna karşılık Office OpenXML’de durum taşıyan, biçimlendirme amaçlı boş etiketler var; DOCX’te ise ardından gelen metnin kalın gösterilip gösterilmeyeceğini açıp kapatıyor
Dosya biçimini SQLite’a bağlamak bir şeylerin yanlış olduğu hissini veriyor
SQLite iyi, ama bu alanda epey benzersiz. Çok fazla iş yaptığı için aynısını yeniden üretmek zor
Ama bu durumda gerçekten bu kadar çok özelliğe ihtiyaç var mı derseniz, yok. Temel ve güvenli işlem semantiği ile basit tablo yapısı saklama yeteneği yeterli; tüm SQL standardına ya da sorgu iyileştiricisine kadar gerek yok
Daha iyi bir dosya biçimi olabilir, ama SQLite’tan ayrı bir biçim olursa daha iyi olurdu
Boyutu 1 MB’tan küçük ve https://sqlite.org/footprint.html, tüm özellikler açıkken bile 750 KB: https://www.sqlite.org/about.html
Derleme zamanında epey özelliği çıkarabiliyorsunuz; sorgu planlayıcıyı ayarlama ya da küçültme seçenekleri de var gibi görünüyor: https://www.sqlite.org/compile.html
Üstelik “SQLite istemci/sunucu veritabanlarıyla rekabet etmez. SQLite
fopen()ile rekabet eder” diye de bir söz var: https://www.sqlite.org/whentouse.htmlSonuçta gereken şey veritabanının kendisi değil, veritabanı API’si ve davranışı sağlayan bir kütüphane
SQLITE_BUSYişleme epey zahmetliydiİşlem işlemede serileştirme hatalarının beklenen bir şey olduğunu biliyorum, ama SQLite’ta kendi kendine kilitlenme gibi kalıcı hatalarla geçici eşzamanlı güncelleme sorunlarını ayırt etmek zordu. Geçici hataysa işlem işini tanımlayan closure’ı yeniden çalıştırmak yeterli, ama kalıcı hataysa anlamsız
Sorunun bir kısmı,
sqlite3_stmt’nin hem hazırlanmış ifade hem de sonuç kümesi niteliğini birleştirmesi. Derlenmiş bytecode’u önbelleğe almak için uzun süre elde tutuluyor; yinelemenin ortasında durursanız o anda kilidi tutuyor olabilir. Bu da beklenmedik kilit yükseltme hatalarına yol açabilirSonunda
sqlite3_next_stmt,sqlite3_stmt_busy,sqlite3_sqlile ayrıntılı hata raporlama oluşturarak sorunu ortadan kaldırdım. Kişisel kullanım içindi, yine de işlem yeniden deneme kodu isteğe bağlı günlükleme ve yorumlarla doluydu. PostgreSQL için işlem yeniden deneme mantığı çok daha kolaydıBir başka şaşırdığım nokta,
synchronous=NORMALolan WAL modunda commit edilmiş işlemlerin güç kaybı veya sistem çökmesi sonrası geri alınabileceğini söyleyen dokümantasyondu: https://sqlite.org/pragma.html#pragma_synchronousBenim uygulamam için ilgili değildi
Richard Hipp ve şirketinin asla dışına çıkmadığı bir ISO/IEC/ANSI/ETSI SQLite standardı, etki edecek patent olmadığına dair hukuki inceleme ve tüm avantajları koruyan birden fazla uyumlu SQLite uygulaması gösterilirse, o zaman dosya biçimi olarak önerilmesini tartışabiliriz. Aksi hâlde bu, tek kaynaklı bir uygulamaya güçlü bir bağımlılık koyup bunu kullanıcıya da yükleyin demek
XML, ASN.1, JFIF resmî standartlar; ZIP de OpenDocument standartlaştırma sürecinde ISO/IEC 21320-1:2015 olarak kabul edilmiş resmî bir standart
Belgelerde en önemli şey, başka herkesin okuyabilmesidir. Disk güncelleme süresini azaltmak ikincil bir iştir. Microsoft’un bağımlılığı sürdürmek için standart kuruluşlarını nasıl çarpıttığından hiçbir şey öğrenmemiş olmamalıyız: https://arstechnica.com/uncategorized/2008/10/norwegian-standards-body-implodes-over-ooxml-controversy/
Bu kadar yanlış bir seçim olamaz
Başka bir örnek de raster harita karoları. Aslında sayıları milyonlara kadar çıkabilen küçük kare görseller
Zip, tar, dosya sistemi ve SQLite’ın hepsini denedik; SQLite en hızlı ve en küçük olanıydı, hatta ek yükü olmayan sıradan arşivlerden bile daha iyiydi
SQLite’ın büyük bir dezavantajı var. Veritabanından alınan BLOB
mmapedilemez; başka bir yere kopyalanması gerekir. Zip dosyaları ise sıkıştırılmamışsa ya da PVRTC gibi özel bir kodlamayla sıkıştırılmışsa doğrudanmmapedilebilirOpenDocument sıkıştırılmış görsellerden ve XML’den oluşur. Sonuçta bu, tüm biçimi ayrıştırıp belleğe almak anlamına gelir
SQLite’ın bunu nasıl iyileştirdiğini pek anlayamıyorum. XML ideal olmasa da Zip ile sıkıştırıldığı için boyut cezası da büyük değil
SQLite yazısında sıralanan tüm avantajlar, SQLite’ı belgenin çalışma zamanı modeli olarak kullanırsanız uygulanabilir. Bu hem diskte hem bellekte mümkün, ancak SQLite’ın aktarım biçimi olması gerekmez
Aksine SQLite mevcut biçimden daha büyük hale gelebilir. Değişikliklerden sonra kullanılmayan alan oluşur; parçalanabilir ve seyrekleşebilir. Her seferinde optimize etmek gerekiyorsa hızlı kaydetme gibi avantajlar da ortadan kalkar
Delta güncellemelerine ve hızlı dizin aramalarına ihtiyaç duyan, dosyanın tamamını belleğe almaması gereken biçimler gerçekten de SQLite’ı dosya biçimi olarak sıkça kullanıyor. Ancak OpenDocument’ın bu varsayımsal senaryoda SQLite hedefi olarak seçilmek için kötü bir örnek olduğunu düşünüyorum
SQLite’ı disk biçimi olarak kullanıp uygulamayı doğru şekilde uygularsanız bozuk bir durumda kalmayabilir
XML/Zip ile de yeniden adlandırma hilesiyle benzer bir sonuç elde edilebilir, ama SQLite bunu tek bir disk dosyası içinde sunar. SQLite’ı zaten bellek modeli olarak kullanıyorsanız, disk/aktarım biçimi olarak da kullanmamak için bir neden yok. O noktada neredeyse bedavaya gelir
Dosya boyutu sorunu
VACUUMile çözülebilir gibi görünüyor