2009-03-21 2 views
1

Meine Anwendung ist datenbankgesteuert. Jede Zeile enthält die Hauptinhaltsspalte, die in einem UIWebView angezeigt wird. Die meisten Zeilen (die Inhaltsspalte) haben einen Verweis auf image1 und einige auf image2. Ich konvertiere diese in base64 und füge die Bildzeichenfolge in die Zeile ein. Wenn sich jedoch ein Bild ändert, bedeutet dies, dass ich durch alle Zeilen zurückgehen und die base64-Zeichenfolge aktualisieren muss.Der beste Weg, Bild durch App zu verweisen?

Ich kann eine eindeutige Zeichenfolge im Zeileninhalt wie {image1} angeben. Das bedeutet, ich muss den gesamten Inhalt für diese Zeile durchsuchen und durch die base64-Version des Bildes ersetzen. Diese Bilder befinden sich auch immer am Ende des Zeileninhalts. Ich bin mir nicht sicher, wie wichtig es ist, zuerst den gesamten Inhalt durchzugehen, bevor er ersetzt wird. Gibt es einen besseren Weg, dies zu tun?

Antwort

0

Warum nicht die Bilder in einer Tabelle mit image_ID (eine eindeutige ganze Zahl) und image_data (ein Blob)? Speichern Sie dann in Ihrer Haupttabelle nur die image_ID und führen Sie eine Verknüpfung aus, wenn Sie das tatsächliche Bild benötigen?

Auf eine alternative Interpretation Ihrer Frage (wenn diese Antwort für Sie keinen Sinn macht) warum nicht den Inhalt in drei Felder brechen: Sachen vor dem Bild, das Bild und die Sachen danach. Speichern Sie die image_ID für den mittleren Teil (nicht die Daten - holen Sie das mit einem sql JOIN in der Bildtabelle). Erstellen Sie dann den endgültigen Inhalt mit Verkettung.

+0

Ich denke, dass der Join mehr Logik hinzufügt, als nur den String zu ersetzen. String replace erledigt den Job und hält die base64-Zeichenfolge an einem Ort - der UIWebView-Inhalt wird geladen. Wie stellen Sie sich die Join-Arbeit vor? – 4thSpace

+0

Ich verstehe Ihre Frage vielleicht nicht, aber es klingt, als ob Sie die Bilddaten (potenziell riesig) mit jeder Zeile speichern. Wenn ja, das ist wirklich albern. Ah, aber es gibt eine andere Interpretation (siehe Bearbeiten) ... – MarkusQ

+0

Ich habe nicht verstanden, warum Sie sagen, dass es albern ist. Die Base64-Zeichenfolge befindet sich nur an einer Position. Dein Alternativvorschlag funktioniert auch nicht.Was ist, wenn Sie ein 2., 3. oder 4. Bild brauchen? – 4thSpace

1

Ich hoffe, ich verstehe Ihre Frage richtig.

Wenn die Bilder nicht sehr groß sind, dann ist es wahrscheinlich OK, um nur das Schlüsselwort like zu verwenden, wie in:

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; 

Wenn Sie image = image1, image2 gesetzt, oder was auch immer, dass Sie geben die Element, das Sie aus der Datenbank suchen, ohne Code im Code bearbeiten zu müssen. Ich gehe davon aus, dass Sie SQL kennen, es tut mir leid, wenn das redundante Informationen sind, aber das obige wird Ihre imageDatabase nach allem durchsuchen, das image1, image2 imageValue enthält. Sobald Sie die Zeile gefunden haben, können Sie sie aktualisieren, oder Sie können die WHERE-Klausel mit der SQL-Anweisung UPDATE verwenden, aber ich halte das für etwas gefährlich, da versehentlich mehrere Zeilen aktualisiert werden können, ohne den Inhalt zu überprüfen es ist was du willst.

Auch, wenn Sie Datenbank-Updates mit dies tun, werden Sie eine große Leistungssteigerung finden, indem Sie Ihre Einfügungen und Aktualisierungen mit Transaktionen wie Verpackung:

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); 

Es bereitet und optimiert Ihre Abfrage, bevor sie ausgeführt wird. Ich habe gesehen, dass Insert- und Update-Anfragen mit Transaktionen doppelt so schnell sind.

Wenn die Datenbank sehr groß ist, hat dies eine erhebliche Leistungseinbuße zur Folge, aber die String-Manipulation im Speicher zu tun, verursacht hohe Speicherkosten. Wenn Sie die SQLite LIKE-Methode verwenden, wird die Zeichenfolge-Suche in einer seriellen Weise auf Datenträger ausgeführt und hat weniger Speicherzugriff.

Sobald Sie das spezifische Element gefunden haben, können Sie den regulären Ausdruck suchen und ersetzen nur auf diese bestimmte Zeichenfolge, wodurch der Speicherbedarf des Codes kleiner bleibt.