VT2020-QuestDB-Demo: Difference between revisions
mNo edit summary |
No edit summary |
||
Line 140: | Line 140: | ||
timestamp_sequence(to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'), rnd_long(1,10,2) * 100000L) ts, |
timestamp_sequence(to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'), rnd_long(1,10,2) * 100000L) ts, |
||
rnd_double(0)*8 + 15 temp, |
rnd_double(0)*8 + 15 temp, |
||
rnd_long(0, 10000, 0) sensorId |
rnd_long(0, 10000, 0) sensorId, |
||
rnd_symbol(4, 1, 2, 0) symb |
|||
FROM long_sequence(10000000) x) |
FROM long_sequence(10000000) x), |
||
Index(symb) |
|||
TIMESTAMP(ts) |
TIMESTAMP(ts) |
||
PARTITION BY MONTH; |
PARTITION BY MONTH; |
||
Line 150: | Line 152: | ||
== Exécution == |
== Exécution == |
||
On part maintenant du principe que |
On part maintenant du principe que vous avez 2 tables avec des valeurs temporelles proches, soient grâce au fichier python, soit directement avec les requêtes SQL. |
||
Par la suite les tables utilisés seront <code>euroDollar</code> et <code>livres</code>. Si les votre ont des noms différents, remplacez les dans les requêtes. |
|||
Vous pouvez échantillonner les données de cette manière : |
|||
<syntaxhighlight lang="sql"> |
|||
SELECT avg(euro) |
|||
FROM euroDollar |
|||
SAMPLE BY 1D; |
|||
</syntaxhighlight> |
|||
Le résultat sera la moyenne des valeurs contenus dans la colonne euro par jour. |
|||
Vous pouvez tester les comparaisons simplifié de timestamp avec : |
|||
<syntaxhighlight lang="sql"> |
|||
SELECT * |
|||
FROM livres |
|||
WHERE dateE='2020-11-23'; |
|||
</syntaxhighlight> |
|||
ou bien simplement : |
|||
<syntaxhighlight lang="sql"> |
|||
livres |
|||
WHERE dateE='2020-11-23'; |
|||
</syntaxhighlight> |
|||
avec l'amélioration de ANSI SQL. |
|||
Vous pouvez essayer d'insérer une donnée temporelle plus ancienne que la dernière valeur dans un <code>designated timestamp</code> avec : |
|||
<syntaxhighlight lang="sql"> |
|||
INSERT INTO euroDollar |
|||
VALUES (2.987, 3.456, to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss')); |
|||
</syntaxhighlight> |
|||
QuestDB vous renvoie une erreur. |
|||
Vous pouvez joindre des tables avec des données temporelles non exactes : |
|||
<syntaxhighlight lang="sql"> |
|||
SELECT euro, livre, dateP |
|||
FROM euroData |
|||
ASOF JOIN livres |
|||
</syntaxhighlight> |
|||
Vous pouvez tenter de faire des requêtes lourdes sur la table readings qui a 10 millions de ligne, et remarquer que les temps d'éxécutions sont courts. |
Latest revision as of 21:06, 5 December 2020
Installation
Il n'y a pas d'installation préalable à faire, si ce n'est celle QuestDB disponible ici. Il est également nécessaire de disposer d'un navigateur web tel que Firefox.
Vous pouvez également tester QuestDB en vous rendant sur leur démo en ligne, disponible ici.
Démonstration
Pour rappel, pour lancer la base de données, placez vous dans le dossier bin/ et effectuez la commande
./questdb.sh start
Rendez vous maintenant dans votre navigateur favori et accédez à l'adresse http://localhost:9000 . Vous devriez voir l'interface web de QuestDB.
Si vous souhaitez générez les mêmes données que moi
Si vous ne voulez pas exactement les mêmes données que moi, vous pouvez passer cette étape
Pour avoir le même rendu que pendant ma présentation, il vous faudra récupérer le programme par lequel j'ai généré mes données. Vous pouvez exécuter ce code python qui vous génère 10,000 entrées au format csv, en pensant a changer le chemin du PATH :
import random
PATH = '/home/tom/Documents/vt/data' # entrez ici le chemin vers votre fichier résultat
NB = 10000 # nombre d'entrées que l'on souhaite générer
# retourne le plus petit de 2 entiers.
def mini(a,b):
if a>b:
return a
return b
# Renvoie 2 float tronquées au 4ème chiffre après la virgule.
# Les nouvelles valeurs générés ont un écart d'au plus 0.05 avec la valeur généré
# dans la boucle d'avant.
def valAlea(oldv1, oldv2):
v1 = str(random.uniform(mini(oldv1-0.05,0),oldv1+0.05))
v2 = str(random.uniform(mini(oldv2-0.05,0),oldv2+0.05))
v1 = float(v1[:6])
v2 = float(v2[:6])
return v1, v2
# Renvoie un entier entre min et max sous la forme d'un string.
# Si l'entier est compris entre 0 et 9, rajoute un 0 deavant.
def getRandString(minimum, maximum):
tmp = random.randint(minimum, maximum)
if tmp >= 0 and tmp <= 9:
return '0' + str(tmp)
return str(tmp)
# Pour que la date soit reconnue, il faut qu'il y ait 6 chiffres
# après la virgule. On rajoute donc des zéros jusqu'a obtenir
# 6 chiffres.
def toSize(reste):
while len(reste) < 6:
reste = '0' + reste
return reste
# Renvoie une timestamp générée aléatoirement au format de QuestDB
def getRandTimestamp():
jour = getRandString(1,30)
heure = getRandString(0,23)
minute = getRandString(0,59)
seconde = getRandString(0,59)
reste = toSize(getRandString(000000,999999))
res = '2020-11-' + jour + 'T' + heure + ':' + minute + ':' + seconde + '.' + reste + 'Z\n'
return res
# On initialise les valeurs de départs de v1 et v2
oldv1 = random.random()
oldv2 = random.random()
lv1 = []
lv2 = []
lvdate = []
f = open(PATH,'w')
f.write('euro|dollar|dateP\n') # entête du fichier csv
for i in range(NB):
v1, v2 = valAlea(oldv1, oldv2)
oldv1 = v1
oldv2 = v2
lv1.append(v1)
lv2.append(v2)
date = getRandTimestamp()
lvdate.append(date)
# On trie les dates afin de les avoir de les insérer dans l'ordre croissant.
lvdate.sort()
for i in range(NB):
s = str(lv1.pop(0))+'|'+str(lv2.pop(0))+'|'+lvdate.pop(0)
f.write(s)
f.close()
Importation
Retournez sur l'interface web
Sur la barre de gauche, rendez vous dans la page d'import. Choisissez le fichier où vous avez généré vos données au format csv et importez le.
Attention : le nom de votre fichier sera le nom de votre table. Pensez a choisir un nom simple.
Vous pouvez maintenant revenir dans la console, toujours avec la barre de gauche. Vous pouvez faire une requête pour voir si votre fichier a bien été importé simplement en tapant le nom de la table et en appuyant sur Run.
Si la table n'apparait pas, vous pouvez recharger les tables depuis le disque en appuyant sur le bouton Refresh.
Attention : Il existe un bug encore non résolu lors de l'importation de données en csv qui empêche l'ajout d'une contrainte designated timestamp
. Nous allons donc devoir procéder en 2 étapes.
Une fois cette table crée, nous allons créer notre table finale avec une requête SQL. On part du principe que la table que vous avez importé s'appelle dataTest
:
CREATE TABLE euroDollar AS
(dataTest)
TIMESTAMP(dateP)
PARTITION BY DAY;
On se retrouve avec une table disposant d'un designated timestamp
et partitionné en jour.
Vous pouvez supprimer la table dataTest avec :
DROP TABLE dataTest;
La table livre a été crée de la même manière en modifiant légèrement le programme python.
Générer des données dans la console
Vous pouvez à pressent créer une table directement depuis cette console grâce à cette requête :
CREATE TABLE readings
AS(
SELECT
x ID,
timestamp_sequence(to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'), rnd_long(1,10,2) * 100000L) ts,
rnd_double(0)*8 + 15 temp,
rnd_long(0, 10000, 0) sensorId,
rnd_symbol(4, 1, 2, 0) symb
FROM long_sequence(10000000) x),
Index(symb)
TIMESTAMP(ts)
PARTITION BY MONTH;
Si vous n'avez pas suivi la première étape, vous pouvez recréer une table en changeant readings
par un autre nom.
Exécution
On part maintenant du principe que vous avez 2 tables avec des valeurs temporelles proches, soient grâce au fichier python, soit directement avec les requêtes SQL.
Par la suite les tables utilisés seront euroDollar
et livres
. Si les votre ont des noms différents, remplacez les dans les requêtes.
Vous pouvez échantillonner les données de cette manière :
SELECT avg(euro)
FROM euroDollar
SAMPLE BY 1D;
Le résultat sera la moyenne des valeurs contenus dans la colonne euro par jour.
Vous pouvez tester les comparaisons simplifié de timestamp avec :
SELECT *
FROM livres
WHERE dateE='2020-11-23';
ou bien simplement :
livres
WHERE dateE='2020-11-23';
avec l'amélioration de ANSI SQL.
Vous pouvez essayer d'insérer une donnée temporelle plus ancienne que la dernière valeur dans un designated timestamp
avec :
INSERT INTO euroDollar
VALUES (2.987, 3.456, to_timestamp('2019-10-17T00:00:00', 'yyyy-MM-ddTHH:mm:ss'));
QuestDB vous renvoie une erreur.
Vous pouvez joindre des tables avec des données temporelles non exactes :
SELECT euro, livre, dateP
FROM euroData
ASOF JOIN livres
Vous pouvez tenter de faire des requêtes lourdes sur la table readings qui a 10 millions de ligne, et remarquer que les temps d'éxécutions sont courts.