PostgreSQL baytesi vs smallint []


9

Bir PostgreSQL veritabanına büyük (100Mb - 1 GB) çok kanallı zaman serisi verilerini aktarmak istiyorum. Veriler , verileri tipik olarak her biri birkaç saniyelik "kayıtlar" veya "dönemler" olarak parçalayan EDF biçimindeki dosyalardan gelir . Her çağın kaydı, her veri kanalı için sinyalleri kısa tamsayıların sıralı dizileri olarak tutar.

Dosyaları en kötü durumda BLOB olarak veritabanında saklamak için zorunluyum. Bu göz önüne alındığında, sinyal verilerine dayalı sorguları kolaylaştırmak gibi veritabanındaki verilerle daha fazla şey yapmama izin veren seçenekleri araştırmak istiyorum.

İlk planım verileri her dönem kaydı için bir satır olarak saklamak. Ne tartmaya çalışıyorum gerçek sinyal veri baytea veya smallint [] (hatta smallint [] []) türleri olarak depolamak olup olmadığını. Herkes birini diğerine tavsiye edebilir misiniz? Depolama ve erişim maliyetleri ile ilgileniyorum. Kullanımın bir kez eklenmesi, zaman zaman okunması, asla güncellenmemesi muhtemeldir. Biri daha kolay özel bir tür olarak sarılmış olsaydı ben kayıtları karşılaştırmak analiz etmek için fonksiyonları ekleyebilir böylece o zaman çok daha iyi.

Kuşkusuz ayrıntıda eksikim, bu yüzden açıklığa kavuşturmamı istediklerinize yorum eklemekten çekinmeyin.


2
Bu , 24 - 28 baytlık satır ek yükünü önleyerek çok fazla disk alanı kaydettiğiniz için, yetkili veri modelinde dizi kullanımı için birkaç mantıklı kullanımdan biri olabilir . Diziler de yeterince uzunsa sıkıştırılır ve hat dışında saklanır.
Craig Zil

beldaz, verileri saklama şekliniz, verilere nasıl erişmeyi planladığınız ve ne sıklıkta yapacağınızla ilgilidir. Veriler nadiren sorgulanırsa ve her zaman sadece kayıt başına veri çekmek istiyorsanız, o zaman bir dizideki kayıt başına bir satırın mantıklı olduğunu düşünüyorum. Bununla birlikte, örneğin belirli bir hasta_kimliği için tüm kayıtları almak gibi biraz daha derinlemesine bir sorgulama yapmak isterseniz, belki de depolama yapısında hafif bir iyileştirme önerebiliriz. Sorgu kalıplarınız hakkında herhangi bir fikriniz var mı?
Chris

@Chris Teşekkürler. Ben çok küçük ve ayrı bir ilişki içinde ikamet edebilirsiniz meta veri bileşeni dışarıda bıraktım. Sorgu kalıpları TBD'dir, ancak aynı anda kaydedilen iki farklı dosyayı karşılaştırmak ve eşzamanlı dönemlerden sinyalleri çıkarmak isteyebilirim.
beldaz

@CraigRinger Dizi sıkıştırma konusunda fazla kanıt görmedim. Bunun bir şekilde etkinleştirilmesi gerekiyor mu?
beldaz

Yanıtlar:


11

Herhangi bir cevabın yokluğunda sorunu kendim araştırdım.

Kullanıcı tanımlı işlevler , ve dahil olmak üzere tüm temel türleri işleyebiliyor gibi görünüyor , bu da temsil seçimini fazla etkilemiyor.byteasmallint[]

Vanilya yapılandırmalı bir Windows 7 dizüstü bilgisayarda yerel olarak çalışan bir PostgreSQL 9.4 sunucusunda birkaç farklı sunum denedim. Gerçek sinyal verilerinin saklanması ile ilgili ilişkiler aşağıdaki gibidir.

Tüm dosya için Büyük Nesne

CREATE TABLE BlobFile (
    eeg_id INTEGER PRIMARY KEY,
    eeg_oid OID NOT NULL
);

Kanal başına SMALLINT dizisi

CREATE TABLE EpochChannelArray (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    channel INT,
    signal SMALLINT[] NOT NULL,
    PRIMARY KEY (eeg_id, epoch, channel)
);

Her çağda kanal başına BYTEA

CREATE TABLE EpochChannelBytea (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    channel INT,
    signal BYTEA NOT NULL,
    PRIMARY KEY (eeg_id, epoch, channel)
);

Dönem başına SMALLINT 2D dizi

CREATE TABLE EpochArray (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    signals SMALLINT[][] NOT NULL,
    PRIMARY KEY (eeg_id, epoch)
);

Dönem başına BYTEA dizisi

CREATE TABLE EpochBytea (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    signals BYTEA NOT NULL,
    PRIMARY KEY (eeg_id, epoch)
);

Daha sonra bu ilişkilerin her birine Java JDBC aracılığıyla bir EDF dosyası içe aktardım ve her yüklemeden sonra veritabanı boyutundaki büyümeyi karşılaştırdım.

Dosyalar:

  • Dosya A: 16 kanalın 2706 dönemi, her kanal 1024 örnek (dönem başına 16385 örnek), 85 MB
  • Dosya B: 18 kanal 18 kanal, her kanal 1024 örnek (dönem başına 18432 örnek), 418 MB
  • Dosya C: 20 kanaldan 11746 dönem, her kanal 64 ila 1024 örnek (dönem başına 17088 örnek), 382 MB

Depolama maliyeti açısından, her bir durumda MB olarak kullanılan boyut şöyledir: MB cinsinden depolama maliyeti

Orijinal dosya boyutuna göre, Büyük Nesneler yaklaşık% 30-35 daha büyüktü. Aksine, her çağın bir BYTEA veya SMALLINT [] [] olarak depolanması% 10'dan daha azdı. Her kanalı ayrı bir demet olarak saklamak, BYTEA veya SMALLINT [] olarak% 40 artış sağlar, bu nedenle büyük bir nesne olarak depolamaktan çok daha kötü değildir.

Başlangıçta takdir etmediğim bir şey , PostgreSQL'de "Çok boyutlu dizilerin her boyut için eşleşen uzantılara sahip olması" . Bu, SMALLINT[][]gösterimin yalnızca bir çağdaki tüm kanalların aynı sayıda örneğe sahip olması durumunda çalıştığı anlamına gelir . Bu nedenle Dosya C, EpochArrayilişkiyle çalışamaz .

Erişim maliyetleri gibi terimlerle, bu etrafında oynanan, ama en azından başlangıçta hızlı temsiliydi veri ekleme açısından değil EpochByteave BlobFilebirlikte EpochChannelArrayilk iki sürece 3 kere alarak yavaş.


Akademik bir bakış açısından, sonuçlarınızı çok ilginç buluyorum, ancak pratik açıdan, depolama boyutu büyük endişe mi? Belki de kullanım durumunuzda çok fazla kayıtınız var ve bu yüzden depolama alanı karşılaştığınız bir sorun mu? Bununla birlikte, bu depolama biçiminde, çağ (veya uygun şemadayken kanal) dışındaki herhangi bir arama, her kaydın bir bölümünün okunmasını gerektirir. Başvurunuz için uygun mu?
Chris

Pratik olarak evet, benim için kesinlikle önemlidir, çünkü birkaç TB ham dosya ile uğraşmayı bekliyorum. Ortaya çıkan akım beklediğimden daha düşük olduğu için, ancak belirli bir temsil için% 300 olsaydı kesinlikle bundan kaçınırdım. Sorgulama gelince, çağ ve kanal dışında bir şey tarafından erişmeyi beklemezdim.
beldaz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.