2008-10-11 5 views
2

J'ai une grande collection de données dans un fichier Excel (et des fichiers CSV). Les données doivent être placées dans une base de données (mysql). Cependant, avant d'entrer dans la base de données, il doit être traité. Par exemple, si la colonne 1 est inférieure à la colonne 3, ajoutez 4 à la colonne 2. Il y a quelques règles à respecter avant que l'information ne soit conservée.Conception d'application pour le traitement des données avant la base de données

Quelle serait une bonne conception à suivre pour accomplir cette tâche? (En utilisant java)

Notes complémentaires

Le processus doit être automatisé. Dans le sens où je n'ai pas besoin d'entrer manuellement et de modifier les données. Nous parlons de milliers de lignes de données avec 15 colonnes d'informations par ligne.

Actuellement, j'ai une sorte de conception de la chaîne de responsabilité mis en place. Une classe (Java) pour chaque règle. Quand une règle est faite, elle appelle la règle suivante.

Plus d'infos

En général, il y a environ 5000 lignes par feuille de données. La vitesse n'est pas un gros problème car cette grosse entrée n'arrive pas souvent.

J'ai considéré les baves, mais je n'étais pas sûr que la tâche était assez compliquée pour les drols.

règles Exemple:

  1. Toutes les devises (données dans des colonnes spécifiques) ne doivent pas contenir les symboles monétaires.

  2. Les noms de catégorie doivent être uniformes (par exemple livre cas = bibliothèque)

  3. dates d'entrée ne peuvent pas être futures dates

  4. entrée de texte ne peut contenir que [AZ 0-9 \ s]

etc ..
en outre, si une colonne d'information est invalide, il doit être signalé lorsque le traitement est terminé (ou peut-être arrêter le traitement).

Ma solution actuelle fonctionne. Cependant, je pense qu'il y a place à l'amélioration donc je cherche pour des idéaux quant à la façon dont il peut être amélioré et ou comment d'autres personnes ont traité des situations similaires .

J'ai envisagé (très brièvement) d'utiliser des baves mais je n'étais pas sûr que le travail était assez compliqué pour profiter des baves.

Répondre

1

Si je me fichais de le faire en 1 étape (comme Oli mentionne), je serais probablement utiliser un design pipe and filters. Puisque vos règles sont relativement simples, je ferais probablement quelques classes basées sur des délégués. Par exemple (code C#, Java mais devrait être assez similaire ... peut-être quelqu'un pourrait se traduire?):

interface IFilter { 
    public IEnumerable<string> Filter(IEnumerable<string> file) { 
    } 
} 

class PredicateFilter : IFilter { 
    public PredicateFilter(Predicate<string> predicate) { } 

    public IEnumerable<string> Filter(IEnumerable<string> file) { 
     foreach (string s in file) { 
     if (this.Predicate(s)) { 
      yield return s; 
     } 
     } 
    } 
} 

class ActionFilter : IFilter { 
    public ActionFilter(Action<string> action) { } 

    public IEnumerable<string> Filter(IEnumerable<string> file) { 
     foreach (string s in file) { 
     this.Action(s); 
     yield return s; 
     } 
    } 
} 

class ReplaceFilter : IFilter { 
    public ReplaceFilter(Func<string, string> replace) { } 

    public IEnumerable<string> Filter(IEnumerable<string> file) { 
    foreach (string s in file) { 
     yield return this.Replace(s); 
    } 
    } 
} 

À partir de là, vous pouvez soit utiliser les filtres délégués directement, ou les sous-classe pour les détails. Ensuite, enregistrez-les avec un Pipeline qui les fera passer à travers chaque filtre.

0

Une classe pour chaque règle? Vraiment? Peut-être Je ne comprends pas la quantité ou la complexité de ces règles, mais je voudrais (semi-pseudo-code):

public class ALine { 
    private int col1; 
    private int col2; 
    private int coln; 
    // ... 

    public ALine(string line) { 
     // read row into private variables 
     // ... 

     this.Process(); 
     this.Insert(); 
    } 

    public void Process() { 
     // do all your rules here working with the local variables 
    } 

    public void Insert() { 
     // write to DB 
    } 
} 

foreach line in csv 
    new ALine(line); 
0

Votre méthode d'utiliser des classes pour chaque règle ne semble un peu de poids lourd, mais il a l'avantage d'être facile à modifier et à développer en cas de nouvelles règles.

En ce qui concerne le chargement des données, le chargement en masse est la solution. J'ai lu quelques informaitons qui suggèrent qu'il peut être de trois ordres de grandeur plus rapide que le chargement en utilisant des instructions d'insertion. Vous pouvez trouver des informations à ce sujet here

0

Bulk charger les données dans une table temporaire, puis utiliser sql pour appliquer vos règles. utiliser la table temporaire, comme base pour l'insertion dans la table réelle. supprimez la table temporaire.

1

Je pense que votre méthode est OK. Surtout si vous utilisez la même interface sur chaque processeur.

Vous pouvez également regarder quelque chose appelé Drules, actuellement Jboss-rules. Je l'ai utilisé il y a quelque temps pour une partie de mon application qui est lourde de règles et ce que j'ai aimé c'est que la logique métier peut être exprimée par exemple dans un tableur ou DSL qui est ensuite compilé en Java (runtime et je pense qu'il y a aussi une option de compilation). Cela rend les règles un peu plus succinctes et donc lisibles. C'est aussi très facile à apprendre (2 jours environ).

Voici un lien vers l'opensource Jboss-rules. Chez jboss.com, vous pouvez sans aucun doute acheter une version officiellement maintenue si c'est plus pour le goût de votre entreprise.

0

vous pouvez voir que toutes les différentes réponses viennent de leur propre expérience et perspective. Comme nous ne connaissons pas grand-chose à la complexité et au nombre de lignes dans votre système, nous avons tendance à donner des conseils en fonction de ce que nous avons fait plus tôt.

Si vous souhaitez réduire à une 1/2 solutions pour votre implémentation, essayez de donner plus de détails.

Bonne chance

1

Créez simplement une fonction pour appliquer chaque règle et appelez chaque fonction applicable pour chaque valeur. Je ne vois pas comment cela nécessite une architecture exotique.

0

Ce n'est peut-être pas ce que vous voulez entendre, ce n'est pas la «façon amusante» par tous les moyens, mais il existe un moyen beaucoup plus facile de le faire. Tant que vos données sont évaluées ligne par ligne ... vous pouvez configurer une autre feuille de calcul dans votre fichier Excel et utiliser les fonctions de type feuille de calcul pour effectuer les transformations nécessaires, en référençant les données de la feuille de données brutes. Pour les fonctions plus complexes, vous pouvez utiliser la vba intégrée dans Excel pour écrire des opérations personnalisées.

J'ai utilisé cette approche plusieurs fois et cela fonctionne très bien; C'est juste pas très sexy.

Questions connexes