2009-03-21 19 views
1

私のアプリケーションはデータベース駆動型です。各行には、UIWebViewに表示されるメインコンテンツの列が含まれています。ほとんどの行(コンテンツ列)はimage1への参照を持ち、someはimage2への参照を持っています。私はこれらをbase64に変換し、イメージ文字列を行に追加します。しかし、いずれかのイメージが変更された場合は、すべての行に戻ってbase64文字列を更新する必要があることを意味します。アウトアプリから画像を参照する最良の方法は?

{image1}などの行コンテンツに一意の文字列を提供できます。つまり、その行のコンテンツ全体を検索し、Base64版のイメージに置き換える必要があります。これらのイメージは、常に行コンテンツの最下部にもあります。置き換える前にすべてのコンテンツを最初から最後までどのように処理したらよいかは、パフォーマンスに影響します。これを行うより良い方法はありますか?

答えて

0

なぜimage_ID(一意の整数)とimage_data(blob)というイメージをテーブルに持たないのですか?次に、メインテーブルにimage_IDだけを格納し、実際のイメージが必要な場合は結合を行います。

あなたの質問の別の解釈(答えがあなたには分かりません)では、コンテンツを3つのフィールドに分割してみてください。なぜなら、イメージの前のもの、イメージ、そして後のものです。中間部分のimage_IDを格納します(データではなく、SQL JOINをイメージテーブルに格納します)。その後、連結して最終的なコンテンツを構築します。

+0

私は、結合が単に文字列置換を行うよりも論理を追加すると思います。 String replaceはジョブを実行し、base64文字列を1つの場所、つまりUIWebViewコンテンツのロードに保持します。あなたはどのように結合が働くことを想像していますか? – 4thSpace

+0

私はあなたの質問を理解していないかもしれませんが、イメージデータ(潜在的に巨大)を各行に格納しているように思えます。もしそうなら、これは本当に愚かです。ああ、別の解釈があります(編集を参照してください)... – MarkusQ

+0

私はあなたがそれがばかだと言う理由をキャッチしませんでした。 base64文字列は1つの場所にのみあります。あなたのalt提案はうまくいきません。2番目、3番目、多分4番目の画像が必要な場合はどうなりますか? – 4thSpace

1

あなたの質問を正しく理解していただきたいと思います。

イメージが非常に大きくない場合には、それだけのようなのようなキーワードを使用することはおそらくOKです:

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 =イメージ1、画像2、または何を設定した場合は、あなたを与えるだろうコード内で文字列操作を行うことなくデータベースから探しているアイテム私はあなたがSQLを知っていると仮定しているので、これは冗長な情報ですが、申し訳ありませんが、上記のimage1、image2 imageValueを含むものについては、imageDatabaseを検索します。行を見つけたらUPDATE SQL文でWHERE句を使用することができますが、最初に内容を確認せずに複数の行を誤って更新する可能性があるため、少し危険です。それはあなたが望むものです。

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

それは準備して、それを実行する前に、あなたのクエリを最適化します:あなたはこれでデータベースの更新を行っている場合

また、あなたのような取引にあなたの挿入と更新をラップすることにより、主要なパフォーマンスの向上があります。私は挿入と更新のクエリがトランザクションで2倍速くなるのを見ました。

データベースが非常に大きい場合は、パフォーマンスが大幅に低下しますが、メモリ内で文字列操作を実行するとメモリのコストが高くなります。 SQLite LIKEメソッドを使用すると、文字列の検索はディスク上で逐次実行され、メモリーヒットが少なくなります。

特定のアイテムが見つかったら、正規表現の検索を行い、その特定の文字列だけを置き換えて、コードのメモリフットプリントを小さくすることができます。

関連する問題