Şu anda veri analizi için veritabanı destekli bir web uygulaması çalıştırıyoruz C#.NET sunucudaki EntityFramework ve çoğunlukla istemci tarafında HTML+Javascript çerçeveleri (web tabanlı) ile.
Uygulamamız düzenli olarak kullanıcılar tarafından yüklenen veya diğer altyapı tarafından alınan büyük miktarlarda, yani 1e6 veya daha fazla toplu ölçüm X / Y veri noktalarını alır.
Şu anda MSSQL'DE bir tablo var Values
ile id, series_id as int; x, y, z as float
. Bu tablo BULK INSERT
bir istemci yüklediğinde verilerle doldurulur ve ilişkili meta veriler bir istemciye kaydedilir. Series
masa. Toplam db boyutu şu anda %99,99'u 1 TB'a yaklaşıyor. Values
veri.
Bu yaklaşımın uygulanması basitti, ancak zaman içinde karmaşık ve yavaş hale getiren bazı dezavantajları var:
- önceden işleyen IIS işlemini aşırı yüklememek için parçalara eklemeliyiz (şu anda parça başına 200 ' 000 veri noktası)
- EKLEME sırasında IIS işlem belleği gereksinimleri çok büyük (200MB veri için>1500MB)
- ekleme çok yavaştır (5 milyon kayıt 100mb'dir, bu TOPLU EKLEME kullanılarak bile eklenmesi >30 saniye sürer)
- EKLEME sırasında tüm tablo kilitlenir, yani bir seferde yalnızca bir kullanıcı ekleyebilir
- verileri almak da oldukça yavaştır, 1e6 kayıtlarını istemek bazen >10 saniye sürer
- >1e6 kayıtları olan serileri düzenli olarak silmek, web uygulaması tarafında zaman aşımlarına neden olur.
Veriler hiçbir zaman kısmen seçilmez, bu yüzden gerçekten bir tabloya sahip olmamız gerekmez. ANCAK, istemcilere gönderilmeden önce görüntülenmek üzere 'inceltilir', yani 1e6 kayıtları-varsayılan olarak, yani kullanım durumlarının %99'unda-istemciye gönderilmeden önce 2000 veya 10.000 kayda düşürülür. Bu, istemcide önbelleğe alınır, ancak yeni bir istemci aynı kümeyi isterse, yeniden işlenir. Değerler tablosunda ayrıca bir dizin bulunur series_id
tablonun kendisinden daha fazla disk alanı alır.
Bu depolama formatını kendi veri formatı (CSV veya JSON veya ikili) ile "Değerler" içindeki bir BLOB depolama alanına değiştirmenin mantıklı olup olmayacağını merak ediyorum ve belki de önceden işlenmiş 'azaltılmış' veri kümelerine sahip ek sütunlar görüntülenmek üzere değiştirilmeden istemcilere itilebilir (örn. JSON) içinde. Yani yeni Values
tablo formatı şöyle bir şey olurdu
id, series_id, data(blob), reduced_data(blob)
ve sadece bir tane olurdu Value
her Series
giriş, 1e6 veya daha fazla değil. İndirgenmiş veri kümesi, yüklenen veriler alındığında bir kez oluşturulur ve istemciler istediğinde görüntülenmek üzere kullanılır
Kısmi seçimlerini kaybedeceğim values
kimliğe veya X/Y değerine göre, ancak Değerler hiçbir zaman başka bir şeye göre seçilmez id
veya series_id
yani bu şu anda bir sınırlama değildir. İşte sorularım:
- Bu hiç mantıklı geliyor mu? Büyük bir BLOB veri kümesinin oluşturulmasının ve silinmesinin her zaman 1.000.000 tek kaydın oluşturulmasından ve silinmesinden önemli ölçüde daha hızlı olmasını bekliyorum. Gerçek?
- İkili BLOB veya CSV/JSON/.. BLOB mu? BLOB depolama için en basit yaklaşım elbette büyük bir CSV veya JSON parçası oluşturmak ve veritabanına kaydetmektir (muhtemelen gzipped). Özel bir ikili veri biçimi daha da küçük olacaktır, ancak istemcilere gönderilmeden önce Json'a dönüştürülmesi gerekir.
İkili veri formatlarıyla gelen ek sıkıntıların buna değmeyebileceğine dair bir his var ve CSV/JSON blobunu ikili bir format icat etmekten daha iyi hale getirmek daha iyi. Gerçek?
Farkında bile olmayabileceğim lekelerin diğer dezavantajlarına ne dersiniz? Boyut sınırlamaları bir sorun gibi görünmüyor, varbinary(MAX)
yeterlidir. Blob içindeki değerler üzerinde, yalnızca meta veriler üzerinde (Seri tablosunda bulunan) bir dizine ihtiyacım yok.
Düşünceler?