Timeseries: SQL ou NoSQL?

33

Je me moque des différences générales entre SQL et NoSQL (ou leurs différences traditionnelles).

Je cherche actuellement à modifier le stockage de nos séries chronologiques internes. Ils contiennent tous des données financières provenant de différentes sources. Actuellement, nous stockons nos données dans une base de données propriétaire. C'est vraiment NoSQL, qui a son propre langage de requête.

L'entrée de la communauté m'intéresse: comment stockeriez-vous les données dans une base de données SQL? Quels sont les avantages d'utiliser SQL sur NoSQL, en particulier pour les séries chronologiques? Suis-je fou pour envisager de stocker cela dans SQL?

Notre ensemble de données comprend des millions de séries chronologiques, dont environ 10% contiennent des millions d'enregistrements. Les séries chronologiques sont organisées hiérarchiquement: / Marché / Instrument / Valeur / Fréquence, où:

  • Le marché est une bourse de valeurs, etc., essentiellement un ensemble d'instruments, généralement des instruments similaires.
  • L'instrument est un instrument. Cela pourrait être un indicateur (Brent Crude), une équité (GOOG), etc.
  • La valeur est l'un des multiples types de données pour un instrument. Cela pourrait être un proche, haut, bas, etc.
  • La fréquence est la fréquence d'une série temporelle particulière. Hebdomadaire, quotidien, mensuel, tick, arbitraire, etc.

Comment les données seraient-elles stockées dans une base de données SQL? Une grande table (peut-être partitionnée par quelque chose), une table par marché ou par instrument, une table par série chronologique.

Merci d'avance.

Nicolas
la source
1
Toutes les séries chronologiques contiennent-elles les mêmes métadonnées (c.-à-d. Des colonnes)?
Jack Douglas
1
Cela ressemble à un entrepôt de données ... Voir cela sur SO: stackoverflow.com/q/2684462/27535
gbn
@ jack-douglas: Demandez-vous cela de suggérer un magasin de données orienté colonnes?
Nicolas
3
@Nicolas Non, je ne m'attends pas à ce qu'un SGBDR SQL traditionnel convienne bien à vos données car a) il serait plus facile d'interroger, b) les volumes ne paraissent pas trop grands (des milliards de lignes?) C) le partitionnement par date semble naturel et / ou fonctionnalités standard OLAP. Je posais des questions sur les métadonnées pour déterminer le nombre de tables dont vous avez besoin. Si chaque série chronologique contient des métadonnées uniques, vous avez besoin de millions de tableaux qui ne semblent pas être une bonne idée dans un SGBDR classique, mais je ne pense pas que vous ayez besoin de cela, n'est-ce pas?
Jack Douglas
2
@ Nicolas avez-vous examiné le nouveau connecteur Hadoop pour SQL Server ? En surface, votre scénario semble correspondre.
Mark Storey-Smith

Réponses:

26

En général, pour un tel ensemble de données structuré, je suppose que vous pourriez écrire un format de données personnalisé qui était plus rapide pour la plupart des opérations quotidiennes (c.-à-d. De petites extractions de données à partir d'une heure arbitraire). Certains avantages, tels que les requêtes ad hoc, les accès multiples, la réplication, la disponibilité, etc., présentent probablement l’avantage de passer à un outil de base de données standard. Il est également plus facile de faire appel à de l’aide pour gérer un magasin de données basé sur des normes.

Si on me demandait de configurer une base de données pour stocker ces données, je procéderais comme suit:

Schéma proposé

(1) Les données de base sont placées dans de nombreuses (1000) tables individuelles, chacune contenant deux colonnes:

  1. time: soit un type de données SQL DATETIME, soit un type numérique d'époque (il s'agit de la clé primaire)
  2. valeur: dactylographiée en fonction de vos données. Je choisirais par défaut le flottant simple précision, mais un type de données à virgule fixe pourrait être plus approprié pour les transactions financières. Ceci est probablement non indexé.

Ces tables deviendront assez volumineuses et vous voudrez peut-être les partitionner manuellement par année (par exemple). Mais vous devrez vérifier les performances du système et effectuer les réglages appropriés.

Ces tables ont besoin de noms uniques et il y a plusieurs options. Ils pourraient être lisibles par l’homme (par exemple, nyse_goog_dailyhighs_2010) ou aléatoires. Dans les deux cas, un ensemble de tables de métadonnées est requis et les noms de table aléatoires empêchent les développeurs d'inférer quoi que ce soit dans le nom qui n'était pas censé être inféré.

(2) Les métadonnées sont stockées dans des tables séparées, comme requis par l'application :

Une table supplémentaire ou un ensemble de tables est nécessaire pour suivre les métadonnées. Ces tableaux contiendront des données sur l’échange, l’instrument, la valeur, la fréquence, les plages de dates, la provenance (d’où viennent les données), ainsi que sur tout ce dont vous avez besoin. Ceux-ci sont mappés aux noms de table de données.

Si le nombre de données est suffisant, cette recherche pourrait en fait fournir un nom de table et un nom de base de données, permettant ainsi une sorte de partage de données auto-implémenté (s'il s'agit de l'utilisation correcte du terme). Mais je garderais cela en réserve.

Ensuite, au niveau de la couche application, j'interroge les tables de métadonnées pour déterminer où se trouvent mes données, puis j'effectue des requêtes relativement simples sur les tables de données volumineuses pour obtenir mes données.

Avantages:

  • Mon expérience (relativement limitée) est que les bases de données peuvent généralement gérer un grand nombre de petites tables plus facilement qu'un petit nombre de grandes tables. Cette approche facilite également la maintenance (par exemple, purger les anciennes données, reconstruire une table corrompue, créer / recharger à partir de sauvegardes, ajouter une nouvelle entité). Cela sépare complètement les différents types de données, si (par exemple) vous avez des données à des débits différents ou si vous avez besoin de types de données différents.

  • Ce concept de table maigre devrait également permettre un accès rapide au disque pour ce que je soupçonne être la requête la plus courante, une plage contiguë de données provenant d'une seule entité. La plupart des applications de données sont limitées en entrées / sorties sur disque, cela vaut donc la peine d'être pris en compte. Comme un intervenant l’a déjà laissé entendre, c’est l’application idéale pour une base de données orientée colonne, mais je n’ai pas encore trouvé de produit orienté colonne suffisamment grand pour que je puisse miser sur ma carrière. Ce schéma devient assez proche.

Désavantages:

  • Environ la moitié de votre espace disque est consacrée au stockage des horodatages, alors que 100 ou 1000 des tables ont exactement les mêmes données dans la colonne timestamp. (En fait, ceci est une exigence si vous souhaitez effectuer des jointures de table faciles).

  • Stocker des noms de table et effectuer une recherche dynamique nécessite beaucoup de complexité d’application et d’opérations sur les chaînes, ce qui me fait crasher. Mais cela semble toujours meilleur que les alternatives (discuté ci-dessous).

Considérations:

  • Attention à ne pas arrondir dans votre champ de temps. Vous voulez que vos valeurs soient suffisamment arrondies pour permettre les jointures (le cas échéant), mais suffisamment précises pour ne pas être ambiguë.

  • Faites attention aux fuseaux horaires et à l'heure avancée. Ce sont difficiles à tester. J'appliquerais une exigence UTC sur le magasin de données (ce qui peut me rendre impopulaire) et gérer les conversions dans l'application.

Variations:

Certaines variations que j'ai considérées sont les suivantes:

Pliage de données: si la série temporelle est à égale distance, utilisez une colonne d'horodatage et (par exemple, 10 colonnes de données). L'horodatage fait maintenant référence à l'heure de la première colonne de données et les autres colonnes de données sont supposées équidistantes entre cet horodatage et la suivante. Cela économise une grande quantité de stockage qui était utilisé auparavant pour stocker des horodatages, au prix d'une complexité de requête et / ou d'application importante. La plage contiguë, les requêtes à entité unique nécessitent désormais moins d'accès au disque.

Multiplexage: si plusieurs séries chronologiques sont connues pour utiliser la même série temporelle, utilisez un horodatage et (par exemple) 10 colonnes de données, comme décrit ci-dessus. Mais maintenant, chaque colonne représente une série temporelle différente. Cela nécessite une mise à jour de la table de métadonnées, qui n'est pas une recherche dans le nom de la table et de la colonne. L'espace de stockage est réduit. Les requêtes restent simples. Cependant, les requêtes à entité unique nécessitent désormais beaucoup plus d’accès au disque.

Méga-tables: poussons à l'extrême le concept de "multiplexage" et regroupent toutes les données dans un seul tableau, une fois par série chronologique. Cela nécessite de grandes quantités d’accès au disque pour les requêtes contiguës, à entité unique, et constitue un cauchemar de maintenance. Par exemple, l'ajout d'une nouvelle entité nécessite désormais une commande MODIFY TABLE sur plusieurs tables de la tuberculose.

Pour plus d'informations sur ce format, reportez-vous aux différentes réponses de: Trop de colonnes dans MySQL

Table entièrement normalisée: au lieu d'utiliser de nombreuses tables à 2 colonnes, vous pouvez utiliser une table à une colonne, où les colonnes sont heure, identifiant de données et valeur. Désormais, vos tables de métadonnées n'ont plus besoin que de rechercher des valeurs d'ID, plutôt que des noms de tables ou des noms de colonnes, ce qui permet d'insérer davantage de logique dans les requêtes SQL, plutôt que dans la couche d'application.

Environ les 2/3 de l'espace de stockage sont maintenant utilisés avec les colonnes de normalisation, de sorte que cela utilisera beaucoup d'espace disque.

Vous pouvez utiliser un ordre de clé primaire de (dataid, timestamp) pour les requêtes rapides, contiguës, à entité unique. Ou, vous pouvez utiliser un ordre de clé primaire de (timestamp. Dataid) pour des insertions plus rapides.

Cependant, même après avoir pris en compte ces variations, mon plan pour mon prochain développement consiste en un grand nombre de tableaux, deux colonnes chacun. Ça, ou la méthode sera bientôt publiée par quelqu'un de plus sage que moi :).

Poursuite
la source
Merci beaucoup pour votre réponse. Vous avez soulevé des points très valables. Je suis complètement d'accord avec le stockage en UTC. J'impose l'idée que toutes les données soient transmises aux interfaces (Web, ordinateurs de bureau et mobiles) en UTC. Nous avons des clients multinationaux, et le système d'exploitation devrait être responsable de la conversion du temps. Une entreprise de DBA travaille sur l’ensemble de notre ensemble de données et je me demandais ce que les autres proposeraient. Merci encore.
Nicolas
Tandis que les consultants DBA travaillent sur le ciblage d’une installation exigeante de SQL Server, je vais procéder à des tests avec une configuration BigData.
Nicolas
C’est peut-être une bonne solution, mais l’application réelle "série chronologique" devrait prendre en charge la fonctionnalité de "zoom sur les données", et la base de données ne peut rien y faire. Les bases de données temporelles sont plus axées sur le "zoom avant" et le "zoom arrière" intelligents.
Roman Pokrovskij
1

Utilisez MongoDB, vous pouvez créer des collections à la volée très rapidement. Organisez vos données dans des bases de données distinctes et des collections au sein de ces bases de données. Pensez à la quantité de mémoire dont vous aurez besoin pour conserver chaque fragment dans la mémoire système, si vous avez besoin d'une récupération rapide. C'est idiot de s'en tenir à une solution maison, s'il y a quelque chose de plus frais qui va évoluer selon les lignes que vous avez besoin. Cela semble être une bonne initiative.

Dantalion
la source
2
Comment stockeriez-vous la série chronologique à Mongo? Chaque document est une série temporelle? ou la valeur d'un horodatage spécifique?
RockScience
Pour le faire efficacement pour des données non périodiques, voire périodiques, il est préférable de pré-allouer des blocs de données. Chaque bloc serait un document contenant une petite quantité de données de comptabilité, un tableau de taille fixe pour vos valeurs et un tableau de taille fixe pour vos temps. Vous stockeriez ensuite vos métadonnées pour la série dans un document séparé. Dans ce document de métadonnées, conservez un petit document imbriqué qui servira de responsable comptable pour vos segments de données, c'est-à-dire le suivi de l'index de tableau actuel et le segment _id.
RYS