Jika saya memahami pemikiran Anda dengan benar, Anda sedang mempertimbangkan untuk menyimpan deret waktu di PostgreSQL, satu catatan deret waktu dalam satu baris database. Jangan lakukan itu.
Di satu sisi, masalahnya adalah teoretis. Basis data relasional (dan saya pikir sebagian besar basis data) didasarkan pada premis independensi baris, sedangkan catatan deret waktu dipesan secara fisik. Tentu saja, indeks database menyediakan beberapa urutan untuk tabel database, tetapi urutan itu dimaksudkan untuk mempercepat pencarian atau untuk menyajikan hasil menurut abjad atau dalam urutan lain; itu tidak menyiratkan makna alami apa pun pada tatanan itu. Terlepas dari cara Anda memesannya, setiap pelanggan tidak bergantung pada pelanggan lain, dan setiap pembelian pelanggan tidak bergantung pada pembelian lainnya, bahkan jika Anda bisa mendapatkannya secara kronologis untuk membentuk riwayat pembelian pelanggan. Saling ketergantungan catatan deret waktu jauh lebih kuat, yang membuat basis data relasional tidak sesuai.
Dalam praktiknya, ini berarti bahwa ruang disk yang diambil oleh tabel dan indeksnya akan sangat besar (mungkin 20 kali lebih besar daripada menyimpan deret waktu dalam file), dan membaca deret waktu dari database akan sangat lambat, seperti perintah besarnya lebih lambat daripada menyimpan dalam file. Itu juga tidak akan memberi Anda manfaat penting. Anda mungkin tidak akan pernah membuat kueri "beri saya semua catatan deret waktu yang nilainya lebih besar dari X". Jika Anda membutuhkan kueri seperti itu, Anda juga akan membutuhkan analisis lain yang tidak dirancang untuk dilakukan oleh basis data relasional, jadi Anda akan tetap membaca seluruh rangkaian waktu ke dalam beberapa objek.
Jadi setiap deret waktu harus disimpan sebagai file. Ini bisa berupa file di sistem file, atau gumpalan di database. Terlepas dari kenyataan bahwa saya telah menerapkan yang terakhir, saya percaya yang pertama lebih baik; di Django, saya akan menulis sesuatu seperti ini:
class Timeseries(models.model):
name = models.CharField(max_length=50)
time_step = models.ForeignKey(...)
other_metadata = models.Whatever(...)
data = models.FileField(...)
Menggunakan FileField
akan membuat database Anda lebih kecil dan membuat cadangan tambahan sistem Anda menjadi lebih mudah. Juga akan lebih mudah untuk mendapatkan irisan dengan mencari di file, sesuatu yang mungkin tidak mungkin atau sulit dengan gumpalan.
Sekarang, jenis file apa? Saya akan menyarankan Anda untuk melihat panda. Ini adalah pustaka python untuk analisis matematis yang mendukung deret waktu, dan juga harus memiliki cara untuk menyimpan deret waktu dalam file.
Saya menautkan di atas ke perpustakaan saya yang tidak saya rekomendasikan untuk Anda gunakan; di satu sisi tidak melakukan apa yang Anda inginkan (tidak dapat menangani granularitas lebih dari satu menit, dan memiliki kekurangan lain), dan di sisi lain sudah usang - saya menulisnya sebelum panda, dan saya berniat untuk mengubahnya untuk menggunakan panda di masa depan. Ada sebuah buku, "Python untuk analisis data", oleh penulis panda, yang menurut saya sangat berharga.
Pembaruan (2016): Ada juga InfluxDB. Tidak pernah menggunakannya dan oleh karena itu saya tidak punya pendapat, tapi itu pasti sesuatu yang perlu Anda periksa jika Anda bertanya-tanya bagaimana cara menyimpan deret waktu.
Pembaruan (07-02-2020): Ada juga TimescaleDB, ekstensi dari PostgreSQL.
Pembaruan (07-08-2020): Kami mengubah perangkat lunak kami (lagi) sehingga menyimpan data dalam database menggunakan TimescaleDB. Kami sudah berpengalaman dalam PostgreSQL dan mudah untuk mempelajari beberapa TimescaleDB. Keuntungan nyata yang paling penting adalah kita dapat membuat kueri seperti "menemukan semua lokasi dengan curah hujan>50 mm dalam 24 jam di 2019", sesuatu yang akan sangat sulit saat menyimpan data dalam file datar. Keuntungan lain adalah pemeriksaan integritas—selama bertahun-tahun kami memiliki beberapa deret waktu dengan baris duplikat karena bug kecil di sana-sini. Kekurangannya juga signifikan. Ini menggunakan 10 kali lebih banyak ruang disk. Kami mungkin perlu mengubah kebijakan pencadangan PostgreSQL kami karena itu. Ini lebih lambat. Mungkin perlu satu detik untuk mengambil deret waktu dengan 300 ribu catatan. Ini adalah instan sebelumnya. Kami perlu menerapkan caching untuk mengambil deret waktu, yang sebelumnya tidak diperlukan.