2009-03-21 8 views
1

Mon application est basée sur une base de données. Chaque ligne contient la colonne de contenu principal que j'affiche dans un UIWebView. La plupart des lignes (la colonne de contenu) ont une référence à image1 et d'autres à image2. Je les convertis en base64 et ajoute la chaîne d'image dans la rangée. Cependant, si l'une ou l'autre des images change, cela signifie que je dois parcourir toutes les lignes et mettre à jour la chaîne base64.La meilleure façon de référencer l'image à travers l'application?

Je peux fournir une chaîne unique dans le contenu de la ligne tel que {image1}. Cela signifie que je devrai faire une recherche dans tout le contenu de cette ligne et la remplacer par la version base64 de l'image. Ces images sont également toujours au bas du contenu de la ligne. Vous ne savez pas comment passer en revue tout le contenu avant de le remplacer aura une incidence sur les performances. Y a-t-il une meilleure manière de faire cela? Pourquoi ne pas avoir les images dans une table, avec image_ID (un entier unique) et image_data (un blob)?

Répondre

0

Ensuite, dans votre table principale, stockez juste l'image_ID, et faites une jointure si vous avez besoin de l'image réelle? Sur une interprétation alternative de votre question (si cette réponse ne vous fait pas de sens), pourquoi ne pas diviser le contenu en trois champs: les choses avant l'image, l'image et les choses après. Stockez l'image_ID pour la partie du milieu (pas les données - obtenez cela avec un sql JOIN sur la table des images). Ensuite, construisez le contenu final avec la concaténation.

+0

Je pense que la jointure ajoute plus de logique que de simplement remplacer la chaîne. String remplace le travail et conserve la chaîne base64 au même endroit - la charge de contenu UIWebView. Comment envisagez-vous la jointure de travail? – 4thSpace

+0

Je ne comprends peut-être pas votre question, mais il semble que vous stockiez les données d'image (potentiellement énormes) avec chaque ligne. Si c'est le cas, c'est vraiment stupide. Ah, mais il y a une autre interprétation (voir edit) ... – MarkusQ

+0

Je n'ai pas compris pourquoi vous dites que c'est bête. La chaîne base64 est seulement dans un emplacement. Votre suggestion alt ne fonctionne pas non plus.Que faire si vous avez besoin d'une 2e, 3e ou peut-être 4e image? – 4thSpace

1

J'espère que je comprends votre question correctement.

Si les images ne sont pas très grand, alors il est probablement OK pour simplement utiliser le mot-clé comme comme dans:

sqlite3_stmt *statement = nil; 
if(statement == nil) 
{ 
    const char *sql = [[NSString stringWithFormat:@"SELECT imageContent FROM imageDatabase WHERE imageContent LIKE '%@%@%@'", @"%", imageValue, @"%"] UTF8String]; 
    if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) != SQLITE_OK) { 
     //NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db)); 
     return; 
    } 
} 
while (sqlite3_step(statement) == SQLITE_ROW) { 
    // query was successful 
    // perform some action on the resulting data 
} 
sqlite3_finalize(statement); 
statement = nil; 

Si vous définissez imageValue = image1, image2, ou autre, qui vous donnera la élément que vous recherchez dans la base de données sans avoir à faire de manipulation de chaîne dans le code. Je suppose que vous connaissez SQL, donc désolé si c'est une information redondante, mais ce qui précède va chercher votre imageDatabase pour tout ce qui contient l'image1, image2 imageValue. Une fois que vous avez trouvé la ligne, vous pouvez la mettre à jour, ou vous pouvez utiliser la clause WHERE avec l'instruction UPDATE SQL, mais je trouve cela un peu dangereux car il est possible de mettre plusieurs lignes par inadvertance sans vérifier le contenu c'est ce que tu veux.

De plus, si vous faites des mises à jour de base de données avec cela, vous trouverez un gain de performances important en enveloppant vos insertions et mises à jour avec des transactions:

const char *sql = "BEGIN TRANSACTION;"; 
    char *errMsg; 
    sqlite3_exec(db, sql, nil, 0, &errMsg); 

const char *commit = "COMMIT;"; 
    sqlite3_exec(db, commit, nil, 0, &errMsg); 

Il prépare et optimise votre requête avant de l'exécuter. J'ai vu des requêtes d'insertion et de mise à jour obtenir deux fois plus vite avec les transactions.

Si la base de données est très volumineuse, cela aura un impact significatif sur les performances, mais la manipulation de la chaîne en mémoire aura un coût en mémoire important. Si vous utilisez la méthode SQLite LIKE, la recherche de chaîne est effectuée en série sur le disque et a moins d'impact sur la mémoire.

Une fois que vous avez trouvé l'élément spécifique, vous pouvez effectuer une recherche d'expression régulière et la remplacer par cette seule chaîne en réduisant l'empreinte mémoire de votre code.

Questions connexes