2009-07-31 5 views
1

J'ai un fichier de 2 Mo, pas trop grand, que je voudrais mettre dans une base de données sqlite pour que je puisse le chercher. Il y a environ 30K entrées au format CSV, avec six champs par ligne. Ma compréhension est que sqlite sur l'iPhone peut gérer une base de données de cette taille.Lire un fichier volumineux dans la table sqlite dans l'objectif-C sur l'iPhone

J'ai pris quelques approches mais elles ont toutes été lentes> 30 s. J'ai essayé:

1) En utilisant le code C pour lire le fichier et analyser les champs en tableaux.

2) En utilisant le code suivant Objective-C pour analyser le fichier et le mettre en directement dans la base de données SQLite:

NSString *file_text = [NSString stringWithContentsOfFile: filePath usedEncoding: NULL error: NULL]; 

NSArray *lineArray = [file_text componentsSeparatedByString:@"\n"]; 

for(int k = 0; k < [lineArray count]; k++){ 
    NSArray *parts = [[lineArray objectAtIndex:k] componentsSeparatedByString: @","]; 

    NSString *field0  = [parts objectAtIndex:0]; 
    NSString *field2  = [parts objectAtIndex:2]; 
    NSString *field3  = [parts objectAtIndex:3]; 

NSString *loadSQLi = [[NSString alloc] initWithFormat: @"INSERT INTO TABLE (TABLE, FIELD0, FIELD2, FIELD3) VALUES ('%@', '%@', '%@');",field0, field2, field3]; 


    if (sqlite3_exec (db_table, [loadSQLi UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) { 
     sqlite3_close(db_table); 
     NSAssert1(0, @"Error loading table: %s", errorMsg); 
    } 

Est-ce que je manque quelque chose? Est-ce que quelqu'un sait d'un moyen rapide pour obtenir le fichier dans une base de données?

Ou est-il possible de traduire le fichier dans un format sqlite qui peut être lu directement dans sqlite? Ou devrais-je transformer le fichier en un plist et le charger dans un dictionnaire? Malheureusement, j'ai besoin de chercher sur deux des champs, et je pense qu'un dictionnaire ne peut avoir qu'une seule clé?


Louis, merci pour votre réponse.

J'aurais dû mentionner que je veux seulement écrire les données dans la base de données une fois au début de l'application, et plus tard je n'ai besoin que de faire des lectures de la base de données, pas d'écriture.

Pouvez-vous me dire comment générer la base de données sqlite3 directement à partir du fichier CSV dans le cadre du processus de construction?

Répondre

1

OK, je pense que je l'ai. A partir de l'invite de commande Unix, ce qui suit se lit dans le fichier CSV et écrit un fichier SQL:

% sqlite3 
sqlite3> .mode csv 
sqlite3> create table NEWTABLE (ITEM_ID INTEGER PRIMARY KEY, FIELD0 TEXT, FIELD1 TEXT, FIELD2 TEXT, FIELD3 TEXT, FIELD4 TEXT, FIELD5 TEXT); 
sqlite3> .import csvfile.csv NEWTABLE 
sqlite3> .output csvfile.sql 
sqlite3> .dump NEWTABLE 

La partie que je n'ai toujours pas compris est que s'il y a un moyen rapide de lire le fichier sql dans sqlite3. L'approche que j'ai actuellement est de lire chaque ligne du fichier sql et de l'exécuter sur l'iPhone. Existe-t-il une approche d'une ligne pour lire le fichier sql dans sqlite3?

+1

Vous ne voulez pas vider le fichier. Cela vous donne une série sérialisée d'instructions SQL qui peuvent être utilisées pour recréer une base de données, pas une base de données elle-même.Il suffit d'exécuter sqlite3 un chemin et il créera le fichier db là "sqlite3/path/to/my/db". Si ce fichier est lisible par l'homme, ce n'est pas ce que vous voulez. –

+0

Louis, peux-tu me dire la commande qui exécute "run sqlite3 a path"? Merci. –

+0

Voulez-vous dire quelque chose comme: % sqlite3 newdatabase.sqlite

1

Je pense que vous êtes confus au sujet de waht sqlite3. Sqlite3 n'est pas une base de données en mémoire, c'est une base de données basée sur disque persistant, si vous chargez toutes vos données dans chaque fois que vous faites quelque chose de mal. SQLite est conçu pour la persistance, après que vous entrez toutes les données, vous pouvez simplement fermer la base de données, et la prochaine fois que vous l'ouvrez en utilisant sqlite3_open_v2(), pas besoin de recharger toutes les données. Par défaut, sqlite3 fait tous ses commits atomiquement (ce qui explique en partie pourquoi les insertions sont lentes), donc vous n'avez même pas besoin de le fermer techniquement (bien que vous le deviez, juste pour être sûr, ou au cas où vous voudriez essayer améliorer les performances en utilisant des transactions). En fait, plutôt que d'inclure un fichier CSV avec l'application, vous pouvez générer la base de données sqlite3 à partir du fichier CSV dans le cadre de votre processus de construction et l'inclure avec l'application.

Questions connexes