Zaman serisi verilerini depolamak için gerçekten 'en iyi yol' yok ve dürüst olmak gerekirse birçok faktöre bağlı. Ancak, öncelikle olmak üzere iki faktöre odaklanacağım:
(1) Bu proje şemayı optimize etme çabanızı hakettiği için ne kadar ciddi?
(2) Sorgu erişim kalıplarınız gerçekte nasıl olacak?
Bu sorular göz önünde bulundurularak, birkaç şema seçeneğini tartışalım.
Düz masa
Düz bir masa kullanma seçeneğinin soru (1) ile daha çok ilgisi var; bu ciddi veya büyük ölçekli bir proje değilse, şema hakkında fazla düşünmemeyi çok daha kolay bulacaksınız sadece düz bir masa kullanın:
CREATE flat_table(
trip_id integer,
tstamp timestamptz,
speed float,
distance float,
temperature float,
,...);
Bu kursu tavsiye edebileceğim pek fazla durum yok, ancak bu, zamanınızı çok fazla garanti etmeyen küçük bir proje ise.
Boyutlar ve Gerçekler
Öyleyse, (1) sorusunun engelini çözdüyseniz ve daha fazla performans şeması istiyorsanız, bu göz önünde bulundurulması gereken ilk seçeneklerden biridir. Bazı temel normailizasyonları içerir, ancak “boyutsal” büyüklükleri ölçülen “gerçek” büyüklüklerinden çıkarır.
Temel olarak, gezilerle ilgili bilgileri kaydetmek için bir masa isteyeceksiniz,
CREATE trips(
trip_id integer,
other_info text);
ve zaman damgalarını kaydetmek için bir tablo,
CREATE tstamps(
tstamp_id integer,
tstamp timestamptz);
ve son olarak tüm ölçülen gerçekler, boyut tablolarına yabancı referanslar ( meas_facts(trip_id)
referanslar trips(trip_id)
ve meas_facts(tstamp_id)
referanslar tstamps(tstamp_id)
) ile
CREATE meas_facts(
trip_id integer,
tstamp_id integer,
speed float,
distance float,
temperature float,
,...);
Bu, ilk bakışta hepsi yardımcı olacak gibi görünmeyebilir, ancak örneğin binlerce eşzamanlı seyahatiniz varsa, hepsi saniyede bir kez, ikincisinde ölçümler alıyor olabilir. Bu durumda, tstamps
tablodaki tek bir girişi kullanmak yerine, her yolculuk için zaman damgasını her seferinde yeniden kaydetmeniz gerekir .
Kullanım örneği: Veri kaydettiğiniz birçok eşzamanlı gezi varsa ve bu durumda tüm ölçüm türlerine birlikte erişmeye aldırış etmezseniz bu durum iyi olacaktır.
Postgres satırlarla okuduğundan, istediğiniz zaman, örneğin speed
belirli bir zaman aralığında ölçümler meas_facts
yaptığınızda, üzerinde çalıştığınız veri kümesinin çalışmasına rağmen kesinlikle bir sorguyu yavaşlatan tablodaki satırın tamamını okumalısınız. çok büyük değil, o zaman farkı bile anlamazsın.
Ölçülen Gerçeklerin Ayrılması
Son bölümü biraz daha genişletmek için, ölçümlerinizi ayrı tablolara bölebilirsiniz, örneğin hız ve mesafe tablolarını göstereceğim:
CREATE speed_facts(
trip_id integer,
tstamp_id integer,
speed float);
ve
CREATE distance_facts(
trip_id integer,
tstamp_id integer,
distance float);
Elbette, bunun diğer ölçümlere nasıl uzatılabileceğini görebilirsiniz.
Kullanım örneği: Yani bu size bir sorgu için muazzam bir hız kazandırmaz, belki bir ölçüm türü hakkında sorgulama yaparken hızdaki doğrusal bir artış olabilir. Bunun nedeni, hız hakkında bilgi aramak istediğinizde, speed_facts
tablonun bir satırında mevcut olacak tüm ekstra, gereksiz bilgiler yerine yalnızca tablodaki satırları okumanız gerektiğidir meas_facts
.
Bu nedenle, yalnızca bir ölçüm türüyle ilgili devasa veri yığınlarını okumanız gerekir, bunun bir faydası olabilir. Bir saniyelik aralıklarla önerilen 10 saatlik veri durumunuzla, yalnızca 36.000 satır okuyacağınız için, bunu yapmanın hiçbir zaman önemli bir faydasını bulamayacaksınız. Ancak, yaklaşık 10 saat süren 5.000 seyahat için hız ölçüm verilerine bakıyorsanız, şimdi 180 milyon satır okumayı düşünüyorsunuz. Böyle bir sorgu için hızdaki doğrusal bir artış, bir seferde yalnızca bir veya iki ölçüm türüne erişmeniz gerektiği sürece, bazı faydalar sağlayabilir.
Diziler / HStore / & TOAST
Muhtemelen bu kısım için endişelenmene gerek yok, ama önemli olduğu durumları biliyorum. Erişmeye gerekiyorsa BÜYÜK zaman serisi miktarlarda veri ve size bir büyük blokta her şeyi erişmesi gereken biliyorsun, kullanımı yapacak bir yapı kullanabilirsiniz TOST Tablolar sıkıştırılmış esasen daha büyük verilerinizi depolar, segmentleri. Bu, amacınız tüm verilere erişmek olduğu sürece verilere daha hızlı erişim sağlar.
Örnek bir uygulama olabilir
CREATE uber_table(
trip_id integer,
tstart timestamptz,
speed float[],
distance float[],
temperature float[],
,...);
Bu tabloda, tstart
dizideki ilk giriş için zaman damgasını saklar ve sonraki her giriş sonraki saniye için bir okuma değeri olur. Bu, bir uygulama yazılımındaki her bir dizi değer için ilgili zaman damgasını yönetmenizi gerektirir.
Başka bir olasılık
CREATE uber_table(
trip_id integer,
speed hstore,
distance hstore,
temperature hstore,
,...);
ölçüm değerlerinizi (anahtar, değer) çiftleri (zaman damgası, ölçüm) olarak eklediğiniz yere.
Kullanım örneği: Bu, PostgreSQL'de daha rahat birisine bırakılmış ve yalnızca toplu erişim düzenleri olması gereken erişim düzenlerinden eminseniz, muhtemelen daha iyi bir uygulamadır.
Sonuçlar?
Vay, bu beklediğimden çok daha uzun sürdü, üzgünüm. :)
Temel olarak, bir dizi seçenek var, ancak muhtemelen daha genel davaya uygun olduklarından, ikinci ya da üçüncüyü kullanarak paranın karşılığını en büyük şekilde alacaksınız.
Not: İlk sorunuz, toplandıktan sonra verilerinizi toplu olarak yükleyeceğiniz anlamına geliyordu. Verileri PostgreSQL örneğinize aktarıyorsanız, hem veri alımınızı hem de sorgu iş yükünüzü işlemek için daha fazla iş yapmanız gerekecek, ancak bunu başka bir zaman bırakacağız. ;)