PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Django + Postgres + Grandes séries temporelles

Si je comprends bien vos pensées, vous envisagez de stocker la série chronologique dans PostgreSQL, un enregistrement de série chronologique dans une ligne de base de données. Ne fais pas ça.

D'une part, le problème est théorique. Les bases de données relationnelles (et je pense que la plupart des bases de données) sont basées sur le principe de l'indépendance des lignes, alors que les enregistrements d'une série chronologique sont physiquement ordonnés. Bien sûr, les index de base de données fournissent un certain ordre pour les tables de base de données, mais cet ordre est destiné à accélérer la recherche ou à présenter les résultats par ordre alphabétique ou dans un autre ordre; il n'implique aucune signification naturelle à cet ordre. Quelle que soit la manière dont vous les commandez, chaque client est indépendant des autres clients et l'achat de chaque client est indépendant de ses autres achats, même si vous pouvez les obtenir dans l'ordre chronologique afin de constituer l'historique des achats du client. L'interdépendance des enregistrements de séries chronologiques est beaucoup plus forte, ce qui rend les bases de données relationnelles inappropriées.

En pratique, cela signifie que l'espace disque occupé par la table et ses index sera énorme (peut-être 20 fois plus grand que le stockage des séries chronologiques dans des fichiers), et la lecture des séries chronologiques à partir de la base de données sera très lente, quelque chose comme une commande d'une ampleur plus lente que le stockage dans des fichiers. Cela ne vous apportera également aucun avantage important. Vous n'allez probablement jamais faire la requête "donnez-moi tous les enregistrements de séries chronologiques dont la valeur est supérieure à X". Si jamais vous avez besoin d'une telle requête, vous aurez également besoin d'un enfer d'autres analyses que la base de données relationnelle n'a pas été conçue pour effectuer, de sorte que vous lirez la série temporelle entière dans un objet de toute façon.

Ainsi, chaque série temporelle doit être stockée sous forme de fichier. Il peut s'agir soit d'un fichier sur le système de fichiers, soit d'un blob dans la base de données. Malgré le fait que j'ai implémenté ce dernier, je pense que le premier est meilleur; dans Django, j'écrirais quelque chose comme ça :

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

Utiliser un FileField réduira la taille de votre base de données et facilitera les sauvegardes incrémentielles de votre système. Il sera également plus facile d'obtenir des tranches en cherchant dans le fichier, ce qui est probablement impossible ou difficile avec un blob.

Maintenant, quel type de fichier ? Je vous conseille de jeter un œil aux pandas. C'est une bibliothèque python pour l'analyse mathématique qui prend en charge les séries temporelles, et elle devrait également avoir un moyen de stocker les séries temporelles dans des fichiers.

J'ai lié ci-dessus à une de mes bibliothèques que je ne vous recommande pas d'utiliser ; d'une part, il ne fait pas ce que vous voulez (il ne peut pas gérer une granularité plus fine qu'une minute, et il a d'autres défauts), et d'autre part, il est obsolète - je l'ai écrit avant les pandas, et j'ai l'intention de le convertir utiliser les pandas à l'avenir. Il y a un livre, "Python pour l'analyse des données", par l'auteur de pandas, que j'ai trouvé inestimable.

Mise à jour (2016) : Il y a aussi InfluxDB. Je ne l'ai jamais utilisé et donc je n'ai pas d'opinion, mais c'est certainement quelque chose que vous devez examiner si vous vous demandez comment stocker des séries temporelles.

Mise à jour (2020-02-07) : Il y a aussi TimescaleDB, une extension de PostgreSQL.

Mise à jour (2020-08-07) : Nous avons (encore) modifié notre logiciel pour qu'il stocke les données dans la base de données à l'aide de TimescaleDB. Nous connaissons déjà PostgreSQL et il était facile d'apprendre TimescaleDB. L'avantage concret le plus important est que nous pouvons effectuer des requêtes telles que "trouver tous les endroits où il y a eu> 50 mm de pluie dans les 24 heures en 2019", ce qui serait très difficile lors du stockage de données dans des fichiers plats. Un autre avantage est les contrôles d'intégrité - au fil des ans, nous avons eu quelques séries chronologiques avec des lignes en double à cause de petits bogues ici et là. Les inconvénients sont également importants. Il utilise 10 fois plus d'espace disque. Nous devrons peut-être modifier notre politique de sauvegarde PostgreSQL à cause de cela. C'est plus lent. Il faut peut-être une seconde pour récupérer une série chronologique avec 300 000 enregistrements. C'était juste avant. Nous devions implémenter la mise en cache pour récupérer les séries chronologiques, ce qui n'était pas nécessaire auparavant.