2011-06-02 3 views
1

J'ai une énorme quantité de données (stockées dans le fichier, mais ce n'est pas pertinent - la partie principale est que les données ne rentrent pas dans la mémoire) - disons 10 lignes d'enregistrements.Regroupement rapide et regroupement d'un énorme ensemble de données

L'enregistrement comprend l'heure, un jeu de clés et des données. Les clés ne sont pas uniques.
par exemple

keys:   data: 
A | B | C |  
---------------------- 
1 | 2 | 3 | 10 
1 | 1 | 3 | 150 
1 | 1 | 2 | 140 
1 | 2 | 5 | 130 
5 | 3 | 2 | 120 
... 

je dois passer par toutes les données, et filtrer les utiliser le filtre défini par l'utilisateur (ce n'est pas problème), puis ensemble, compter somme, et retourner les lignes avec des données le plus élevé .

Par exemple, dans les données fournies, je veux résumer chaque groupe de données par A et C.

résultat attendu:

A | C | data 
------------ 
1 | 3 | 160 
1 | 2 | 140 
1 | 5 | 130 

------------ following (data isn't in 3 highest value) doesn't concern me. 
5 | 2 | 120 

j'ai mis cela en utilisant la solution naïve, je Dictionary<tuple(A, C), long>, et somme Là. Mais le problème est, qu'il peut y avoir plus de combinaisons uniques de A, C que je peux entrer dans la mémoire.

Je ne peux pas pré-additionner l'une des données, car aucun filtrage ne peut apparaître, ni utiliser SQL (DB relationnel ne correspond pas bien pour moi).

Existe-t-il des algorithmes efficaces en mémoire utilisables pour le regroupement de cette façon? Comment SQL gère-t-il autant de données? Je suis capable de faire le regroupement sur SQL, mais il y a quelques raisons pour lesquelles je ne veux pas l'utiliser.

Ou, que devrais-je google? Je n'ai trouvé aucun article utile sur cette question.

(j'utilise C#, la question est plutôt théorique que « utilisez le code suivant: »)

+0

avez-vous envisagé d'utiliser mapreduce? il semble parfaitement en forme! http://static.googleusercontent.com/external_content/untrusted_dlcp/labs.google.com/en//papers/mapreduce-osdi04.pdf – amit

+0

@amit: non, je n'en ai jamais entendu parler. merci pour le lien, je vais jeter un coup d'oeil. – nothrow

+0

mapreduce est un cadre pour couper des données en morceau, d'abord vous le 'mappez' en paires: (clé, valeur) et ensuite donné une liste de valeurs pour chaque touche, vous faites votre étape 'reduce' (votre résumé). il était à l'origine implémenté en C++, mais hadoop est une version java, et je suppose qu'une version C# est également disponible. bonne chance! – amit

Répondre

1
bien

, les commentaires de la question pourraient être considérés comme une réponse ...
Vous pouvez utiliser mapreduce (hadoop est la mise en œuvre du cadre en Java)
votre étape map analysera chaque ligne et extraira la clé et la valeur pertinentes pour chaque ligne.
votre étape reduce résumera toutes les données pour la clé donnée.

+0

En fait, j'ai essayé d'utiliser cette approche, je ne savais tout simplement pas que cela s'appelle map/reduce. Le problème est, que l'ensemble de données est assez énorme, même après la réduction finale (avant que tout 'obtenir seulement le top 5' s'applique). Je peux le diviser en plus petits groupes, et sélectionner 'top5' parmi eux, mais cela pourrait renvoyer des données erronées. – nothrow

+0

(il peut y avoir même 10^9 lignes qui ont des clés uniques - je ne suis pas capable de détecter cela) – nothrow

+0

le cadre map/reduce devrait s'en charger pour vous (si vous utilisez une bibliothèque existante).d'ailleurs, tant que vos données sont plus petites que 2^system_bits, même si les données ne rentrent pas dans la RAM, le système d'exploitation s'en chargera en échangeant des données sur le disque, donc pratiquement, le système 64bits ne rencontrera pas ce problème. – amit