Entrepôt de données: comment interroger des instantanés quotidiens?

9

J'ai quelques instantanés d'une base de données qui ne sont pas des séries temporelles. Par exemple:

  • Instantané jour 1:

    +----+---------------+------------+------------+        
    | ID |     Title     |  Category  |    Date    |
    +----+---------------+------------+------------+
    | 1  | My First Post | helloworld | 2015-01-01 |
    +----+---------------+------------+------------+
  • Instantané jour 2 (un nouveau message est ajouté aujourd'hui):

    +----+----------------+------------+------------+        
    | ID |      Title     |  Category  |    Date    |
    +----+----------------+------------+------------+
    | 1  | My first post  | helloworld | 2015-01-01 |
    | 2  | My second post | other      | 2015-01-02 |
    +----+----------------+------------+------------+
  • Instantané jour 3 (le post 2 est supprimé aujourd'hui):

    +----+---------------+------------+------------+        
    | ID |     Title     |  Category  |    Date    |
    +----+---------------+------------+------------+
    | 1  | My First Post | helloworld | 2015-01-01 |
    +----+---------------+------------+------------+

Ainsi, entre les jours, une ligne du tableau peut ou non être constante. Maintenant, je dois pouvoir utiliser une requête comme celle-ci:

SELECT category, COUNT(*) from day1.My_table group by category

C'est pour une table d'une journée. Si nous voulons compter la moyenne quotidienne des messages par catégorie dans un mois, nous devons faire quelque chose comme:

SELECT category, SUM(cnt) / 30 
from ( 
    SELECT category, COUNT(*) as cnt 
    from day1.My_table 
    group by category 
        UNION ALL SELECT category, COUNT(*) as cnt 
                  from day2.My_table 
                  group by category 
        UNION ALL ... 
        UNION ALL SELECT category, COUNT(*) as cnt 
                  from day30.My_table 
                  group by category
) group by category

Autre exemple, le nombre d'articles publiés dans un mois :

SELECT COUNT(distinct id) 
from ( 
    SELECT id 
    from day1.My_table 
    UNION ALL ... 
    UNION ALL SELECT id 
              from day30.My_table
) 

Fondamentalement, nous aurions besoin de considérer un poids. Si nous avons day1.My_table et day5.My_table, chaque message qui est au jour1 et non au jour5 sera compté comme il l'était également au jour 2,3,4. Chaque publication de jour1 et de jour5 comptera comme si elle se trouvait tous les jours du mois (= jusqu'au prochain instantané).

Donc, au cas où je voudrais considérer le nombre moyen de messages par jour de> = 6 mois par coup, où je n'ai qu'un instantané, j'attribuerais à cet instantané un poids de 30.

Ainsi, la publication moyenne publiée dans un mois pour une plage> = il y a 6 mois est:

SELECT category, SUM(cnt) / 30 
from ( 
    SELECT category, COUNT(*)*30 as cnt 
    from day1.My_table 
    group by category --- Note: I'm not considering the range defined from the user in this example.
) group by category;

Comme le commentaire l'a également déclaré, je devrais faire une requête comme:

Select category, AVG(*) 
from [fromRange-toRange].MyTable; 

Pour une solution extrême, j'envisage l'idée d'implémenter un métalangage pour permettre au futur utilisateur (ex. Marketng people) de faire une requête comme celle-ci.

Pensez-vous qu'il existe un moyen d'accomplir cela dans Drill sans le méta-langage? Je le ferais en utilisant un UDF récursif mais ils ne peuvent pas retourner de requêtes.

Chaque instantané fait 250 Go, et je veux pouvoir comparer ces jeux de données avec d'autres données externes (je ne connais pas au préalable le schéma de ces jeux de données).

Existe-t-il une solution adaptée à Apache Drill? Ou existe-t-il une autre solution à ce problème?

Tout méta-langage ou article sur ce problème est également apprécié.

Edit: Nous n'avons pas de données transactionnelles. Nous avons des données qui changent dans le temps et peuvent être ajoutées ou supprimées; pour cette raison, nous avons besoin d'instantanés quotidiens. De plus, nous ne savons pas à l'avance les requêtes qui seront effectuées, nous ne pouvons donc pas savoir quel type d'agrégation effectuer. De plus, chaque ligne a environ 100 colonnes, et il y a par exemple 250 Go par instantané (tables Mysql). Nous avons également besoin d'une recherche plein texte sur ces données sur chaque ligne, chaque jour possible.

Un exemple de recherche pourrait être "Combien de messages étaient sur quelque chose?" Il doit donc rechercher dans tous les messages le mot-clé. Chaque instantané peut ou non avoir les mêmes lignes. De plus, deux instantanés pourraient avoir le même message, mais légèrement modifiés.

Federico Ponzi
la source
Il semble que vous ayez une structure décente pour vos données. Y a-t-il une raison particulière pour laquelle vous recherchez une solution sans schéma? Par schéma, je supposetable definitions/structures
vmachan
Parce que je ne veux pas définir de nouvelles tables avant de charger mes jeux de données. Bien sûr, s'il existe une solution qui peut gérer ce problème mais a besoin d'une table à définir à l'avance, je la choisirais de toute façon.
Federico Ponzi
Des instantanés quotidiens de 250 Go? Avec ces exigences? Comment?
Tom V - essayez topanswers.xyz
Pourquoi des instantanés quotidiens? Quelle proportion des 250 Go change par jour? Qu'est-ce qui ne va pas avec une approche de dimensions à évolution lente?
dnoeth
Veuillez ne pas penser ce problème en termes d'entreposage de données, mais en termes de requête et / ou de Big Data. J'ai différents instantanés quotidiens de ma base de données et je voudrais un moyen de les interroger efficacement.
Federico Ponzi

Réponses:

2

Pensons hors de la boîte. Au lieu d'avoir un "instantané", nous allons avoir un "journal". Ce que vous avez actuellement, c'est l'état actuel des choses; l'ajout d'un "journal" fournirait l '"historique", dont pourraient dériver les informations "perdues".

Une façon d'implémenter le journal est d'avoir un TRIGGERsur INSERTou UPDATEde la table et d'avoir le déclencheur en écriture dans le fichier journal. Ce journal ne sera pas agréable pour les requêtes ad hoc, alors ayez un travail de nuit (ou peut-être toutes les heures) qui résume les changements pour la journée - gain (ou perte) net de nombre de messages, etc. Les informations "jour2" et les informations "du mois dernier" peuvent alors être dérivées de ce tableau récapitulatif assez rapidement. Ou peut-être un deuxième niveau de résumé qui déclare l'état de chaque jour. Je doute que UNIONce soit nécessaire. Le «cliché» ne serait pas impliqué.

Rick James
la source
1
J'ai demandé comment interroger des instantanés quotidiens, vous parlez simplement d'une optimisation - j'y penserai plus tard. Merci
Federico Ponzi
1
Les instantanés sont difficiles à gérer (à mon avis), alors j'essayais de présenter un moyen de résoudre le «vrai» problème au lieu de se laisser entraîner dans une solution difficile. En outre, le résumé permettra des requêtes beaucoup plus rapides.
Rick James
2

Donc, ce que je cherchais, c'est un nouveau type de système lié au Datawarehousing: Data Lake System.

Vous pouvez en savoir plus sur Wikipedia :

Un lac de données est une méthode de stockage de données dans un système qui facilite la colocation de données dans des schémas et des formes structurelles variables, généralement des objets blob ou des fichiers. Hadoop et la plate-forme AWS S3 peuvent être utilisés pour créer des référentiels de lacs de données.

Federico Ponzi
la source