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.
Réponses:
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:
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 :).
la source
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.
la source