Quel est le moyen le plus efficace de stocker des mesures avec un nombre variable de champs dans une base de données?

StackOverflow https://stackoverflow.com/questions/1629458

  •  06-07-2019
  •  | 
  •  

Question

Nous disposons d’un système de collecte de données qui recueille des mesures à partir de capteurs environnementaux qui mesurent la vitesse de circulation de l’eau dans une rivière ou un canal. Chaque mesure génère un nombre fixe de valeurs (date, heure, température, pression, etc.) et une liste de valeurs de vélocité.
A l'origine, les capteurs fournissaient trois valeurs de vélocité, j'ai donc simplement stocké chaque valeur dans sa propre colonne d'une seule table dans une base de données FireBird. Plus tard, nous avons introduit des capteurs capables de générer jusqu'à neuf valeurs de vélocité, j'ai donc ajouté six colonnes supplémentaires. Même si la plupart des capteurs utilisent moins de 9 valeurs, je pensais que ce ne serait pas un problème si la plupart des colonnes ne contenaient que des zéros.
Mais maintenant, je suis confronté à une nouvelle génération capable de générer de 1 à 256 valeurs et je suppose qu’il ne sera pas très efficace d’ajouter 247 colonnes supplémentaires, d’autant plus que la plupart des mesures ne contiennent encore que 3 à 9 valeurs.
Étant donné que les mesures sont collectées toutes les 10 minutes et que la base de données contient toutes les données de 30 à 50 capteurs, la quantité totale de données est assez importante après quelques années, mais il doit être possible de générer des vues d'ensemble / des graphiques pour toute période aléatoire.

Alors, quel serait le moyen le plus efficace de stocker la liste de variables de valeurs?
Étant donné que chaque enregistrement a son propre ID unique, je suppose que je pourrais simplement stocker toutes les valeurs de vélocité dans une table distincte, chaque valeur étant étiquetée avec son ID d'enregistrement. J'ai simplement le sentiment que cela ne serait pas très efficace et que cela deviendrait très lent après un certain temps.

Était-ce utile?

La solution

Les bases de données peuvent gérer de grandes quantités de données dans une table si vous utilisez des index efficaces. Vous pouvez donc utiliser cette structure de table:

create table measurements (
     id,
     seq integer, -- between 1 and 256
     ts timestamp, -- Timestamp of the measurement
     value decimal(...)
)

Créez un index sur id , id, seq et ts . Cela vous permettra de rechercher efficacement dans les données. Si vous ne faites pas confiance à votre base de données, insérez quelques millions de lignes et exécutez quelques sélections pour vérifier son efficacité.

À titre de comparaison: j'ai ici une base de données Oracle avec 112 millions de lignes et je peux sélectionner un enregistrement par horodatage ou ID dans un délai de 120 ms (0,12 s)

Autres conseils

Vous pouvez enregistrer des données sérialisées dans un champ de texte, par exemple en codant JSON les mesures comme suit:

[<velocity-value-1>, <velocity-value-2>, ...]

Ensuite, dans votre code, désérialisez les valeurs après une requête.

Cela devrait bien fonctionner si vous ne filtrez vos requêtes que par les autres champs, et non par les valeurs enregistrées. Si vous filtrez les valeurs, les utiliser dans les clauses WHERE sera un cauchemar.

J'irais avec un deuxième tableau:

table measurements (Id, DateTime, Temperature, Pressure)
table velocity (Id, MeasurementId, Sequence, Value)

Velocity.MeasurementId fait référence à Measurements.Id .
Velocity.Squence est l'indice de la valeur de vélocité pour cette mesure (1-256).

Remplissez ces tables avec des données aussi proches que possible du monde réel et testez les instructions SQL pour trouver les meilleurs index.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top