我的应用程序是数据库驱动的。每行包含我在UIWebView中显示的主要内容列。大多数行(内容列)都引用了image1,一些引用了image2。我将这些转换为base64并将图像字符串添加到行中。但是,如果任一图像发生更改,则意味着我必须返回所有行并更新base64字符串。
我可以在行内容中提供唯一的字符串,例如{image1}。这意味着我将不得不搜索该行的整个内容,并替换为图像的base64版本。这些图像也始终位于行内容的底部。不确定在更换之前如何首先浏览所有内容会影响性能。有更好的方法吗?
答案 0 :(得分:1)
我希望我能正确理解你的问题。
如果图像不是很大,那么只需使用like关键字就可以了:
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;
如果你设置了imageValue = image1,image2或者其他什么,它将为你提供你正在寻找的项目,而无需在代码中进行字符串操作。我假设你知道SQL,很抱歉,如果这是多余的信息,但上面将搜索你的imageDatabase中包含image1,image2 imageValue的任何内容。一旦找到该行,就可以更新它,或者可以将WHERE子句与UPDATE SQL语句一起使用,但我发现由于无意中更新多行而无需先检查内容以确保它有点危险这就是你想要的。
此外,如果您正在使用此进行数据库更新,您可以通过使用以下事务包装插入和更新来获得显着的性能提升:
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);
它在执行之前准备并优化您的查询。我看到插入和更新查询的事务速度是事务的两倍。
如果数据库非常大,这会有很大的性能损失,但在内存中进行字符串操作会产生很大的内存成本。如果使用SQLite LIKE方法,则字符串搜索在磁盘上以串行方式完成,并且内存命中较少。
找到特定项目后,您可以执行正则表达式搜索并替换该特定字符串,从而使代码的内存占用更小。
答案 1 :(得分:0)
为什么不将图像放在表格中,使用image_ID(唯一整数)和image_data(blob)?然后在主表中,只存储image_ID,如果需要实际图像,可以进行连接吗?
关于你的问题的另一种解释(如果答案对你没有意义),为什么不把内容分成三个字段:图像之前的东西,图像和之后的东西。存储中间部分的image_ID(不是数据 - 使用图像表上的sql JOIN获取)。然后用连接构建最终内容。