sql >> Databasteknik >  >> RDS >> PostgreSQL

Django + Postgres + Large Time Series

Om jag förstår dina tankar rätt överväger du att lagra tidsserien i PostgreSQL, en tidsseriepost i en databasrad. Gör inte det.

Å ena sidan är problemet teoretiskt. Relationsdatabaser (och jag tror att de flesta databaser) är baserade på premissen om radoberoende, medan posterna för en tidsserie är fysiskt ordnade. Naturligtvis ger databasindex en viss ordning för databastabeller, men den ordningen är avsedd att påskynda sökningen eller att presentera resultat alfabetiskt eller i någon annan ordning; det innebär inte någon naturlig betydelse för den ordningen. Oavsett hur du beställer dem är varje kund oberoende av andra kunder, och varje kunds köp är oberoende av hans andra köp, även om du kan få dem helt och hållet kronologiskt för att bilda kundens köphistorik. Det ömsesidiga beroendet mellan tidsserieposter är mycket starkare, vilket gör relationsdatabaser olämpliga.

I praktiken betyder detta att diskutrymmet som tas upp av tabellen och dess index kommer att vara enormt (kanske 20 gånger större än att lagra tidsserierna i filer), och att läsa tidsserier från databasen kommer att vara mycket långsam, ungefär som en order av storleken långsammare än att lagra i filer. Det kommer inte heller att ge dig någon viktig fördel. Du kommer förmodligen aldrig att göra frågan "ge mig alla tidsserieposter vars värde är större än X". Om du någon gång behöver en sådan fråga behöver du också en helvetes annan analys som relationsdatabasen inte är designad för att utföra, så du kommer att läsa in hela tidsserien till något objekt ändå.

Så varje tidsserie bör lagras som en fil. Det kan antingen vara en fil i filsystemet eller en blob i databasen. Trots att jag har implementerat det senare tror jag att det förra är bättre; i Django skulle jag skriva något sånt här:

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

Använda ett FileField kommer att göra din databas mindre och göra det lättare att göra stegvisa säkerhetskopior av ditt system. Det blir också lättare att få tag i skivor genom att söka i filen, något som förmodligen är omöjligt eller svårt med en blob.

Nu, vilken typ av fil? Jag skulle råda dig att ta en titt på pandor. Det är ett pythonbibliotek för matematisk analys som har stöd för tidsserier, och det borde också ha ett sätt att lagra tidsserier i filer.

Jag länkade ovan till ett av mitt bibliotek som jag inte rekommenderar dig att använda; å ena sidan gör den inte som du vill (den kan inte hantera granularitet finare än en minut, och den har andra brister), och å andra sidan är den föråldrad - jag skrev den före pandor, och jag tänker konvertera den att använda pandor i framtiden. Det finns en bok, "Python för dataanalys", av författaren till pandas, som jag har funnit ovärderlig.

Uppdatering (2016): Det finns också InfluxDB. Har aldrig använt det och därför har jag ingen åsikt, men det är definitivt något som du måste undersöka om du undrar hur du lagrar tidsserier.

Uppdatering (2020-02-07): Det finns också TimescaleDB, ett tillägg till PostgreSQL.

Uppdatering (2020-08-07): Vi ändrade vår programvara (igen) så att den lagrar data i databasen med TimescaleDB. Vi är redan bevandrade i PostgreSQL och det var lätt att lära sig lite TimescaleDB. Den viktigaste konkreta fördelen är att vi kan göra frågor som "hitta alla platser där det kom>50 mm regn inom 24 timmar under 2019", något som skulle vara väldigt svårt när man lagrar data i platta filer. En annan fördel är integritetskontrollerna – under åren har vi haft några tidsserier med dubbletter av rader på grund av små buggar här och där. Nackdelarna är också betydande. Den använder 10 gånger mer diskutrymme. Vi kan behöva ändra vår PostgreSQL-säkerhetskopieringspolicy på grund av det. Det är långsammare. Det tar kanske en sekund att hämta en tidsserie med 300 000 rekord. Detta var omedelbart innan. Vi behövde implementera cachning för att hämta tidsserier, vilket inte behövdes tidigare.



  1. Exportera en PostgreSQL-databas med phpPgAdmin

  2. Hur man laddar JDBC-konfiguration från Egenskapsfil Exempel

  3. Oracle Concurrent Manager

  4. ORA-01843 inte en giltig månad- Jämför datum