PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Django + Postgres + Large Time Series

Jeśli dobrze rozumiem Twoje przemyślenia, rozważasz przechowywanie szeregu czasowego w PostgreSQL, jednego rekordu szeregu czasowego w jednym wierszu bazy danych. Nie rób tego.

Z jednej strony problem jest teoretyczny. Relacyjne bazy danych (a myślę, że większość baz danych) opierają się na założeniu niezależności wierszy, podczas gdy rekordy szeregu czasowego są uporządkowane fizycznie. Oczywiście indeksy bazy danych zapewniają pewną kolejność tabel bazy danych, ale ta kolejność ma na celu przyspieszenie wyszukiwania lub prezentację wyników alfabetycznie lub w innej kolejności; nie implikuje to żadnego naturalnego znaczenia tej kolejności. Niezależnie od tego, w jaki sposób je zamówisz, każdy klient jest niezależny od innych klientów, a zakup każdego klienta jest niezależny od jego innych zakupów, nawet jeśli możesz je uzyskać chronologicznie, aby utworzyć historię zakupów klienta. Współzależność rekordów szeregów czasowych jest znacznie silniejsza, co sprawia, że ​​relacyjne bazy danych są nieodpowiednie.

W praktyce oznacza to, że miejsce na dysku zajmowane przez tabelę i jej indeksy będzie ogromne (może 20 razy większe niż przechowywanie szeregów czasowych w plikach), a odczytywanie szeregów czasowych z bazy danych będzie bardzo powolne, coś w rodzaju kolejności o wielkości wolniej niż przechowywanie w plikach. Nie przyniesie to również żadnej istotnej korzyści. Prawdopodobnie nigdy nie zrobisz zapytania „daj mi wszystkie rekordy szeregów czasowych, których wartość jest większa niż X”. Jeśli kiedykolwiek będziesz potrzebować takiego zapytania, będziesz potrzebować również piekielnej innej analizy, do której relacyjna baza danych nie została zaprojektowana, więc i tak wczytasz cały szereg czasowy do jakiegoś obiektu.

Dlatego każdy szereg czasowy powinien być przechowywany jako plik. Może to być plik w systemie plików lub obiekt BLOB w bazie danych. Pomimo tego, że zaimplementowałem to drugie, uważam, że to pierwsze jest lepsze; w Django napisałbym coś takiego:

class Timeseries(models.model):
    name = models.CharField(max_length=50)
    time_step = models.ForeignKey(...)
    other_metadata = models.Whatever(...)
    data = models.FileField(...)

Korzystanie z FileField zmniejszy bazę danych i ułatwi tworzenie przyrostowych kopii zapasowych systemu. Łatwiej będzie również uzyskać plasterki, przeszukując plik, co jest prawdopodobnie niemożliwe lub trudne w przypadku bloba.

Jaki rodzaj pliku? Radzę rzucić okiem na pandy. Jest to biblioteka Pythona do analizy matematycznej, która obsługuje szeregi czasowe, a także powinna umożliwiać przechowywanie szeregów czasowych w plikach.

Zalinkowałem powyżej do mojej biblioteki, której nie polecam używać; z jednej strony nie robi tego, co chcesz (nie radzi sobie z ziarnistością drobniejszą niż minutę i ma inne wady), a z drugiej jest przestarzały - napisałem to przed pandami i zamierzam to przerobić używać pand w przyszłości. Istnieje książka „Python do analizy danych” autora pand, która okazała się bezcenna.

Aktualizacja (2016): Jest też InfluxDB. Nigdy go nie używałem i dlatego nie mam zdania, ale zdecydowanie należy to sprawdzić, jeśli zastanawiasz się, jak przechowywać szeregi czasowe.

Aktualizacja (2020-02-07): Istnieje również TimescaleDB, rozszerzenie do PostgreSQL.

Aktualizacja (2020-08-07): Zmieniliśmy nasze oprogramowanie (ponownie) tak, aby przechowywało dane w bazie danych za pomocą TimescaleDB. Jesteśmy już zaznajomieni z PostgreSQL i łatwo było nauczyć się niektórych TimescaleDB. Najważniejszą konkretną zaletą jest to, że możemy zadawać zapytania typu „znajdź wszystkie lokalizacje, w których w 2019 r. padało>50 mm w ciągu 24 godzin”, co byłoby bardzo trudne przy przechowywaniu danych w płaskich plikach. Kolejną zaletą jest kontrola integralności — przez lata mieliśmy kilka szeregów czasowych ze zduplikowanymi wierszami z powodu drobnych błędów tu i tam. Nie bez znaczenia są również wady. Zajmuje 10 razy więcej miejsca na dysku. Z tego powodu być może będziemy musieli zmienić naszą politykę tworzenia kopii zapasowych PostgreSQL. Jest wolniejszy. Pobranie serii czasowej zawierającej 300 tys. rekordów zajmuje może jedną sekundę. To było chwilę wcześniej. Musieliśmy zaimplementować buforowanie do pobierania szeregów czasowych, co nie było wcześniej potrzebne.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wstawić JSONB do Postgresql za pomocą Pythona?

  2. Wyzwalacz Postgres po uzyskaniu dostępu do insertu NOWOŚĆ

  3. Jak przywrócić plik zrzutu PostgreSQL do baz danych Postgres?

  4. Jak porównać dwie tablice i wybrać tylko niepasujące elementy W postgres

  5. Jak Cos() działa w PostgreSQL