Meilleure conception de base de données et de table pour des milliards de lignes de données [fermé]

74

J'écris une application qui doit stocker et analyser de grandes quantités de données électriques et de température.

J'ai essentiellement besoin de stocker de grandes quantités de mesures horaires de consommation d'électricité au cours des dernières années et des années à venir pour des dizaines de milliers d'emplacements, puis d'analyser les données de manière peu complexe.

Les informations que je dois stocker (pour le moment) sont les suivantes: ID d'emplacement, Horodatage (Date et heure), Température et consommation d'électricité.

À propos de la quantité de données à stocker, c’est une approximation, mais plutôt:
20 000 emplacements, 720 enregistrements par mois (mesures horaires, environ 720 heures par mois), 120 mois (il y a 10 ans) ) et de nombreuses années dans le futur. Des calculs simples donnent les résultats suivants:

20 000 emplacements x 720 enregistrements x 120 mois (10 ans en arrière) = 1 728 000 000 enregistrements .

Il s’agit des enregistrements passés. De nouveaux enregistrements seront importés tous les mois, ce qui représente environ 20 000 x 720 = 14 400 000 nouveaux enregistrements par mois .

Le nombre total d'emplacements augmentera également régulièrement.

Sur toutes ces données, les opérations suivantes devront être exécutées:

  1. Récupérer les données pour une certaine date ET une période: tous les enregistrements pour un certain ID d'emplacement entre les dates 01.01.2013 et 01.01.2017 et entre 07h00 et 13h00.
  2. Opérations mathématiques simples pour une certaine date ET une plage horaire, par exemple température et consommation d’électricité MIN, MAX et AVG pour un certain ID de lieu pendant 5 ans entre 07h00 et 13h00.

Les données seront écrites mensuellement, mais seront lues par des centaines d'utilisateurs (au moins) en permanence, de sorte que la vitesse de lecture est beaucoup plus importante.

Je n'ai aucune expérience des bases de données NoSQL, mais d'après ce que j'ai rassemblé, elles constituent la meilleure solution à utiliser ici. J'ai lu sur les bases de données NoSQL les plus populaires, mais comme elles sont assez différentes et permettent également une architecture de table très différente, je n'ai pas été en mesure de décider quelle est la meilleure base de données à utiliser.

Mes choix principaux étaient Cassandra et MongoDB, mais comme je n’ai que des connaissances très limitées et que je n’ai aucune expérience réelle en ce qui concerne les grandes données et NoSQL, je ne suis pas très certain. J'ai également lu que PostreSQL gère également de telles quantités de données.

Mes questions sont les suivantes:

  1. Devrais-je utiliser une base de données NoSQL pour de telles quantités de données? Sinon, puis-je m'en tenir à MySQL?
  2. Quelle base de données devrais-je utiliser?
  3. Devrais-je conserver la date et l'heure dans des colonnes indexées (si possible) distinctes pour récupérer et traiter les données rapidement pour certaines périodes et dates, ou est-ce possible de le faire en conservant l'horodatage dans une seule colonne?
  4. Une approche de modélisation des données chronologiques est-elle appropriée ici? Sinon, pourriez-vous me donner des indications pour une bonne conception de tableau?

Je vous remercie.

Gecata
la source
29
2017. Bien que n'étant pas petite, il ne s'agit pas d'une GRANDE quantité de données pour un matériel approprié. Et je déteste vous dire, mais jusqu'à présent, ce que vous avez là ressemble à des données relationnelles.
TomTom
6
J'ai stocké dans MS SQL Server 2008-2014 des tables contenant plusieurs dizaines de milliards de lignes en utilisant une bonne clé (date d'époque), une compression, un partitionnement et en veillant à ce que mes requêtes / index soient alignés sur la partition. J'ai dû passer à NoSQL (Hadoop) lorsque j'ai commencé à obtenir des pétaoctets de données à analyser et à indexer différemment. NoSQL devrait avoir d'autres considérations et dans ce cas, cela ne semble pas correspondre.
Ali Razeghi
3
@AliRazeghi Hadoop n'a rien à voir avec SQL ou NoSQL - c'est juste un moteur de stockage. Il existe de nombreuses interfaces SQL supportées par Hadoop.
Mustaccio
3
Quelles sont vos contraintes concernant l'argent à dépenser en logiciels / licences?
user3067860
1
Lorsque vous avez une somme d'argent illimitée, je vous suggère alors d'acheter un appareil SAP HANA. C'est idéal pour les agrégations sur de grands ensembles de données. Mais vous n'avez probablement pas d'argent infini.
Philipp

Réponses:

90

C'est exactement ce que je fais tous les jours, sauf qu'au lieu d'utiliser les données horaires, j'utilise les données de 5 minutes. Je télécharge environ 200 millions de disques par jour, donc le montant dont vous parlez n’est pas un problème. Les données de 5 minutes ont une taille d’environ 2 To et j’ai des données météorologiques remontant à 50 ans à un niveau horaire par lieu. Alors laissez-moi répondre à vos questions en fonction de mon expérience:

  1. N'utilisez pas NoSQL pour cela. Les données sont très structurées et correspondent parfaitement à une base de données relationnelle.
  2. Personnellement, j'utilise SQL Server 2016 et je n'ai aucun problème à appliquer des calculs à ce volume de données. À l'origine, il se trouvait sur une instance PostgreSQL lorsque j'ai démarré mon travail et il ne pouvait pas gérer le volume de données comme il l'était sur une petite instance AWS.
  3. Je recommanderais fortement d' extraire la partie heure de la date et de la stocker séparément de la date elle-même. Croyez-moi, apprenez de mes erreurs!
  4. Je stocke la majorité des données sous forme de liste (DATE, TIME, DATAPOINT_ID, VALUE), mais ce n'est pas ainsi que les gens voudront interpréter les données. Soyez prêt pour des requêtes horribles contre les données et de grandes quantités de pivot. Ne craignez pas de créer une table dé-normalisée pour des jeux de résultats trop volumineux pour être calculés à la volée.

Astuce générale: Je stocke la plupart des données entre deux bases de données. La première est une série chronologique simple et normalisée. Ma deuxième base de données est très dé-normalisée et contient des données pré-agrégées. Aussi rapide que mon système est, je ne suis pas aveugle au fait que les utilisateurs ne veulent même pas attendre 30 secondes pour le chargement d'un rapport - même si je pense personnellement que 30 secondes pour traiter 2 To de données, c'est extrêmement rapide.

Pour expliquer pourquoi je recommande de stocker l'heure séparément de la date, voici quelques raisons pour lesquelles je le fais de cette façon:

  1. La manière dont les données électriques sont présentées est par heure de fin- Par conséquent, 01:00 est en fait la moyenne de l'énergie électrique de l'heure précédente et 00:00 correspond à Hour Ending 24. (Ceci est important car vous devez rechercher deux dates pour inclure la valeur sur 24 heures - le jour sont à la recherche de la première marque du jour suivant.) Toutefois, les données météorologiques sont en fait présentées de manière prospective (réelles et prévues pour la prochaine heure). D'après mon expérience avec ces données, les consommateurs souhaitent analyser les effets du temps sur le prix / la demande en énergie. Si vous utilisiez une comparaison de date directe, vous compareriez en fait le prix moyen de l'heure précédente à la température moyenne de l'heure suivante, même si les horodatages sont identiques.DATETIME colonne.
  2. Performance. Je dirais qu'au moins 90% des rapports que je génère sont des graphiques, représentant normalement le prix par rapport à l'heure, que ce soit pour une date unique ou pour une plage de dates. Le fait de séparer l'heure de la date peut ralentir la vitesse de la requête utilisée pour générer le rapport en fonction de la plage de dates à afficher. Il n’est pas rare que les consommateurs souhaitent voir une seule date, une année sur l’année, au cours des 30 dernières années (en fait, la météo est nécessaire pour générer la normale sur 30 ans) - cela peut être lent. Bien sûr, vous pouvez optimiser votre requête et ajouter des index, et croyez-moi, j'ai des index insensés que je préférerais ne pas avoir, mais le système fonctionne rapidement.
  3. Productivité. Je déteste avoir à écrire le même morceau de code plus d'une fois. J'avais l'habitude de stocker la date et l'heure dans la même colonne, jusqu'à ce que je devais écrire la même requête encore et encore pour extraire la partie heure. Au bout d'un moment, j'en ai eu assez d'être obligé de le faire et l'ai extrait dans sa propre colonne. Moins vous avez de code à écrire, moins il y a de risque d'erreur. En outre, le fait d'écrire moins de code signifie que vous pouvez sortir vos rapports plus rapidement, personne ne veut attendre toute la journée pour les rapports.
  4. Les utilisateurs finaux. Tous les utilisateurs finaux ne sont pas des utilisateurs expérimentés (savoir comment écrire du code SQL). Avoir les données déjà stockées dans un format qu'ils peuvent importer dans Excel (ou un autre outil similaire) avec un minimum d'effort fera de vous un héros au bureau. Si les utilisateurs ne peuvent pas accéder aux données ou les manipuler facilement, ils n’utiliseront pas votre système. Croyez-moi, j'ai conçu le système parfait il y a quelques années et personne ne l'a utilisé pour cette raison. La conception de la base de données ne consiste pas seulement à adhérer à un ensemble prédéfini de règles / directives, il s'agit également de rendre le système utilisable.

Comme je l'ai dit ci-dessus, tout est basé sur mon expérience personnelle, et laissez-moi vous dire que cela a été plusieurs années difficiles et de nombreuses restructurations pour arriver là où je suis maintenant. Ne faites pas ce que j'ai fait, apprenez de mes erreurs et assurez-vous d'impliquer les utilisateurs finaux de votre système (ou les développeurs, auteurs de rapports, etc.) lors de la prise de décisions concernant votre base de données.

Mr.Brownstone
la source
J'ai eu de la chance en utilisant Epoch date, mais votre recommandation est intéressante pour votre cas d'utilisation. Merci d'avoir partagé.
Ali Razeghi
4
Je suis en désaccord avec beaucoup de cela. Rien de tout cela ne pose de réel problème avec une base de données moderne, comme le montrent les chiffres réels . Si les utilisateurs des données sont trop stupides pour utiliser SQL, vous devez alors leur créer une interface - vous ne modifiez pas le schéma. Extraire l'heure est une mauvaise idée
Evan Carroll
1
À quoi ressemble votre matériel?
kennes
1
@kennes physical, 16 cœurs, 256 Go de RAM, disque dur de 100 Go, SSD local de 500 Go avec données TempDB dessus, réseau de stockage hybride avec cache SSD de 8 To et disque dur de 40 To pouvant atteindre 100 000 iops / s. L'implémentation de la base de données utilise ColumnStore, la compression, les tables en mémoire, le partitionnement et une instance SSAS tabulaire.
Brownstone
1
C'est un matériel incroyable en fonction du nombre d'utilisateurs que vous servez. Comme il s’agit d’une réponse pseudo-optimisée, je pense que l’inclusion de votre technologie est utile. J'étais complètement sous le choc d'apprendre que vous pouvez utiliser 2 To en 30 secondes, ce qui est incroyablement rapide. Mon jugement personnel mis à part, je pense que cela serait utile pour les futurs utilisateurs cherchant à optimiser les données de séries chronologiques!
kennes
57

Index PostgreSQL et BRIN

Testez-le vous-même. Ce n'est pas un problème sur un ordinateur portable de 5 ans avec un SSD.

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,  -- fake location ids in the range of 1-20000
    now() AS tsin,                   -- static timestmap
    97.5::numeric(5,2) AS temp,      -- static temp
    x::int AS usage                  -- usage the same as id not sure what we want here.
  FROM generate_series(1,1728000000) -- for 1.7 billion rows
    AS gs(x);

                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..15.00 rows=1000 width=4) (actual time=173119.796..750391.668 rows=1728000000 loops=1)
 Planning time: 0.099 ms
 Execution time: 1343954.446 ms
(3 rows)

Il a donc fallu 22 minutes pour créer la table. En grande partie, parce que la table est un modeste 97GB. Ensuite, nous créons les index,

CREATE INDEX ON electrothingy USING brin (tsin);
CREATE INDEX ON electrothingy USING brin (id);    
VACUUM ANALYZE electrothingy;

La création des index a également pris beaucoup de temps. Bien qu'ils soient BRIN, ils ne font que 2 à 3 Mo et se stockent facilement dans le bélier. La lecture de 96 Go n'est pas instantanée, mais ce n'est pas un réel problème pour mon ordinateur portable au moment de votre charge de travail.

Maintenant nous l'interrogeons.

explain analyze
SELECT max(temp)
FROM electrothingy
WHERE id BETWEEN 1000000 AND 1001000;
                                                                 QUERY PLAN                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=5245.22..5245.23 rows=1 width=7) (actual time=42.317..42.317 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=1282.17..5242.73 rows=993 width=7) (actual time=40.619..42.158 rows=1001 loops=1)
         Recheck Cond: ((id >= 1000000) AND (id <= 1001000))
         Rows Removed by Index Recheck: 16407
         Heap Blocks: lossy=128
         ->  Bitmap Index Scan on electrothingy_id_idx  (cost=0.00..1281.93 rows=993 width=0) (actual time=39.769..39.769 rows=1280 loops=1)
               Index Cond: ((id >= 1000000) AND (id <= 1001000))
 Planning time: 0.238 ms
 Execution time: 42.373 ms
(9 rows)

Mettre à jour avec les horodatages

Ici, nous générons une table avec différents horodatages afin de satisfaire la demande d'indexation et de recherche sur une colonne d'horodatage, la création prend un peu plus de temps car elle to_timestamp(int)est nettement plus lente que now()(mise en cache pour la transaction).

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,
    -- here we use to_timestamp rather than now(), we
    -- this calculates seconds since epoch using the gs(x) as the offset
    to_timestamp(x::int) AS tsin,
    97.5::numeric(5,2) AS temp,
    x::int AS usage
  FROM generate_series(1,1728000000)
    AS gs(x);

                                                               QUERY PLAN                                                                
-----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..17.50 rows=1000 width=4) (actual time=176163.107..5891430.759 rows=1728000000 loops=1)
 Planning time: 0.607 ms
 Execution time: 7147449.908 ms
(3 rows)

Maintenant, nous pouvons exécuter une requête sur une valeur d'horodatage à la place,

explain analyze
SELECT count(*), min(temp), max(temp)
FROM electrothingy WHERE tsin BETWEEN '1974-01-01' AND '1974-01-02';
                                                                        QUERY PLAN                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=296073.83..296073.84 rows=1 width=7) (actual time=83.243..83.243 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=2460.86..295490.76 rows=77743 width=7) (actual time=41.466..59.442 rows=86401 loops=1)
         Recheck Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
         Rows Removed by Index Recheck: 18047
         Heap Blocks: lossy=768
         ->  Bitmap Index Scan on electrothingy_tsin_idx  (cost=0.00..2441.43 rows=77743 width=0) (actual time=40.217..40.217 rows=7680 loops=1)
               Index Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
 Planning time: 0.140 ms
 Execution time: 83.321 ms
(9 rows)

Résultat:

 count |  min  |  max  
-------+-------+-------
 86401 | 97.50 | 97.50
(1 row)

Donc, en 83,321 ms, nous pouvons agréger 86 401 enregistrements dans une table avec 1,7 milliard de lignes. Cela devrait être raisonnable.

Heure se terminant

Calculer la fin de l'heure est assez facile aussi, tronquer l'horodatage vers le bas, puis ajoutez simplement une heure.

SELECT date_trunc('hour', tsin) + '1 hour' AS tsin,
  count(*),
  min(temp),
  max(temp)
FROM electrothingy
WHERE tsin >= '1974-01-01'
  AND tsin < '1974-01-02'
GROUP BY date_trunc('hour', tsin)
ORDER BY 1;
          tsin          | count |  min  |  max  
------------------------+-------+-------+-------
 1974-01-01 01:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 02:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 03:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 04:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 05:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 06:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 07:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 08:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 09:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 10:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 11:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 12:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 13:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 14:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 15:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 16:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 17:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 18:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 19:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 20:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 21:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 22:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 23:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-02 00:00:00-06 |  3600 | 97.50 | 97.50
(24 rows)

Time: 116.695 ms

Il est important de noter qu'il n'utilise pas d'index sur l'agrégation, bien que ce soit le cas. Si c'est ce que vous voulez en général, vous voulez probablement que BRIN date_trunc('hour', tsin)pose un petit problème, car il date_truncn'est pas immuable, vous devez donc d'abord l'envelopper pour qu'il en soit ainsi.

Partitionnement

Un autre point d’information important sur PostgreSQL est que PG 10 apporte le DDL de partitionnement . Ainsi, vous pouvez, par exemple, créer facilement des partitions pour chaque année. Décomposer votre base de données modeste en minuscules. Ce faisant, vous devriez pouvoir utiliser et gérer les index btree plutôt que BRIN, qui serait encore plus rapide.

CREATE TABLE electrothingy_y2016 PARTITION OF electrothingy
    FOR VALUES FROM ('2016-01-01') TO ('2017-01-01');

Ou peu importe.

Evan Carroll
la source
13

Je suis étonné de constater que personne ici n’a mentionné le benchmarking - c’est-à-dire jusqu’à ce que @EvanCarroll apporte son excellente contribution!

Si j'étais vous, je passerais un certain temps (et oui, je sais que c'est un produit précieux!) Pour configurer des systèmes, exécuter ce que vous pensez (obtenez les commentaires de l'utilisateur final ici!), Par exemple vos 10 requêtes les plus courantes.

Mes propres pensées:

Les solutions NoSQL peuvent très bien fonctionner pour des cas d'utilisation particuliers, mais sont souvent inflexibles pour des requêtes ad-hoc. Pour une version amusante de NoSQL par Brian Aker - ancien architecte en chef de MySQL, voir ici !

Je suis d’accord avec @ Mr.Brownstone pour dire que vos données sont parfaitement adaptées à une solution relationnelle (et cette opinion a été confirmée par Evan Carroll )!

Si je devais m'engager dans une dépense, ce serait pour ma technologie de disque! Je dépenserais tout l'argent dont je disposais sur NAS ou SAN ou peut-être des disques SSD pour stocker mes données globales rarement écrites!

D'abord, je regarderais ce que j'ai disponible maintenant . Exécutez des tests et montrez les résultats aux décideurs. Vous avez déjà un proxy sous la forme de travail d' EC ! Mais, un test rapide ou deux fouettés ensemble sur votre propre matériel serait plus convaincant!

Alors pensez à dépenser de l'argent! Si vous envisagez de dépenser de l'argent, examinez d'abord le matériel plutôt que les logiciels. Selon les informations dont vous avez la connaissance, vous pouvez louer la technologie de disque pour une période d’essai ou, mieux, créer quelques preuves de concept sur le cloud.

PostgreSQL est mon premier point de contact personnel pour un projet de ce type. Cela ne veut pas dire que j'éliminerais une solution propriétaire, mais les lois de la physique et des disques sont les mêmes pour tout le monde! "Yae cannae beet les lois de la physique Jim" :-)

Vérace
la source
6

Si vous ne l’avez pas déjà fait, jetez un coup d’œil à un SGBD de séries chronologiques, car il est optimisé pour le stockage et l’interrogation de données dont le principal objectif est le type date / heure. En règle générale, les bases de données de séries chronologiques sont utilisées pour enregistrer des données dans la plage des minutes / secondes / sous-secondes. Par conséquent, je ne suis pas sûr que cela soit toujours approprié pour les incréments horaires. Cela dit, ce type de SGBD semble valoir la peine d’être examiné. Actuellement, InfluxDB semble être la base de données de séries chronologiques la plus établie et la plus utilisée.

FloorDivision
la source
1
Qu'est-ce qu'un exemple de SGBD de série chronologique?
Evêque
2
Regardez ici .
Vérace
4

Clairement, ce n'est pas un problème NoSQL, mais je suggérerais qu'une solution SGBDR puisse fonctionner, mais qu'une approche OLAP conviendrait mieux, et étant donné les plages de données très limitées impliquées, je suggérerais fortement d'envisager l'utilisation d'une base de données basée sur des colonnes. plutôt que basé sur la rangée. Pensez-y de cette façon, vous pourriez avoir 1,7 milliard de données, mais vous n’avez toujours besoin que de 5 bits pour indexer chaque valeur possible d’heure ou de jour du mois.

J'ai déjà travaillé dans un domaine similaire où Sybase IQ (maintenant SAP IQ) stocke jusqu'à 300 millions de compteurs de données de gestion de la performance des équipements télécoms par heure, mais je doute que vous disposiez d'un budget suffisant pour ce type de solution. MariaDB ColumnStore est un candidat très prometteur dans le domaine des logiciels libres, mais je recommanderais également d’enquêter sur MonetDB.

Étant donné que les performances des requêtes sont un facteur important pour vous, prenez en compte le libellé des requêtes. C'est là que OLAP et SGBDR présentent leurs plus grandes différences: - avec OLAP, vous normalisez en fonction des performances des requêtes, et non en réduisant la répétition, le stockage ou même l'application de la cohérence. Donc, en plus de l'horodatage d'origine (vous vous êtes souvenu de capturer son fuseau horaire, j'espère?), Disposez d'un champ distinct pour l'horodatage UTC, d'autres pour la date et l'heure, et encore davantage pour l'année, le mois, le jour, l'heure et la minute. et décalage UTC. Si vous disposez d'informations supplémentaires sur les emplacements, n'hésitez pas à les conserver dans une table d'emplacement séparée qui peut être consultée à la demande. Vous pouvez également conserver la clé de cette table dans votre enregistrement principal tout en conservant le nom complet de l'emplacement dans votre table principale. après tout

En guise de suggestion finale, utilisez des tables distinctes pour les données agrégées courantes et utilisez des travaux par lots pour les renseigner. Ainsi, vous n'avez pas à répéter l'exercice pour chaque rapport qui utilise une valeur agrégée et effectue des requêtes comparant les données actuelles à l'historique ou à l'historique. historique à historique beaucoup plus facile et beaucoup, beaucoup plus rapide.

Paul Smith
la source
Vous pourriez aussi considérer Greenplum comme un magasin de colonnes si vous les regardez! En "bonus" - basé sur PostgreSQL!
Vérace
J'ai eu une bonne expérience avec HP Vertica. Nous avions une seule table avec 9 colonnes contenant 130 milliards de lignes, sans beaucoup de réglages. Cela a juste fonctionné.
ThatDataGuy