次のアップグレードでAndroidデータベースに約700レコードを一括挿入します。これを行う最も効率的な方法は何ですか?さまざまな投稿から、Insert
を使用すると post 独自のデータベースの使用についてもありますが、アプリの標準Androidデータベースに移動するにはこのデータが必要です。これは、デバイスごとに1回だけ実行されることに注意してください。
いくつかのアイデア:
SQLステートメントの束をファイルに入れ、一度に1行ずつ読み取り、SQLを実行します。
データをCSVファイル、JSON、YAML、またはXMLなどに入れます。一度に1行ずつ読み取り、db.insert()
を実行します。
インポートの方法と、ファイル全体の単一インポートの方法を見つけます。
すべてのレコードを含むsqliteデータベースを作成し、それをAndroidデバイスにコピーし、何らかの方法で2つのデータベースをマージします。
[編集]すべてのSQLステートメントをres/valuesの1つのファイルに1つの大きな文字列として入れます。次に、一度に1行ずつ読み取り、SQLを実行します。
最善の方法は何ですか?データをロードする他の方法はありますか? 3と4も可能ですか?
リストの#3または#4を達成するための実行可能な方法があるとは思わない。
他のソリューションのうち、データファイルにダイレクトSQLが含まれる2つと、SQL以外の形式のデータが含まれる2つをリストします。
3つとも問題なく動作しますが、フォーマットされたファイルからデータを取得し、SQLを自分で作成するという後者の提案が最もきれいに見えます。後日、真のバッチ更新機能が追加された場合、データファイルは引き続き使用可能であるか、少なくとも簡単に使用可能な形式に処理できます。また、データファイルの作成はより簡単で、エラーが発生しにくくなります。最後に、「生の」データがあると、他のデータストア形式へのインポートが可能になります。
いずれの場合でも、(前述したように)挿入のグループをトランザクションにラップして、行ごとのトランザクションジャーナルの作成を回避する必要があります。
通常、db.insert()
が使用されるたびに、SQLiteはトランザクション(およびファイルシステム内の結果のジャーナルファイル)を作成します。
db.beginTransaction()
およびdb.endTransaction()
を使用すると、SQLiteはファイルシステム上に単一のジャーナルファイルのみを作成し、すべての挿入を同時にコミットするため、物事が劇的にスピードアップします。
以下にいくつかの擬似コードを示します。 Android上のSQLiteデータベースへのバッチ挿入
_try
{
db.beginTransaction();
for each record in the list
{
do_some_processing();
if (line represent a valid entry)
{
db.insert(SOME_TABLE, null, SOME_VALUE);
}
some_other_processing();
}
db.setTransactionSuccessful();
}
catch (SQLException e) {}
finally
{
db.endTransaction();
}
_
予期しないエラーまたは何かが原因でトランザクションを中止したい場合は、最初にトランザクションを成功として設定せずに、単にdb.endTransaction()
します(db.setTransactionSuccessful()
)。
別の便利な方法は、db.inTransaction()
(true
またはfalse
を返す)を使用して、現在トランザクションの途中にいるかどうかを判断することです。
一括挿入の場合、(明らかにほとんど使用されない) DatabaseUtils.InsertHelper クラスは、SQLiteDatabase.insert
を使用するよりも数倍高速であることがわかりました。
他の2つの最適化もアプリのパフォーマンスに役立ちましたが、すべての場合に適切とは限りません。
bind
のnull
値を使用しないでください。ブログ投稿 に詳細があります。
まあ、これに対する私のソリューションは奇妙ですが、うまく機能します...大量のデータをコンパイルして一度に挿入します(一括挿入?)
db.execSQL(Query)
コマンドを使用し、次のステートメントで「クエリ」を作成します...
INSERT INTO yourtable SELECT * FROM (
SELECT 'data1','data2'.... UNION
SELECT 'data1','data2'.... UNION
SELECT 'data1','data2'.... UNION
.
.
.
SELECT 'data1','data2'....
)
唯一の問題は、クエリを構築することです。私はそれが役立つことを願っています
以下のこの例は完全に機能します
String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
+ " VALUES (?,?,?,?,?,?,?,?,?);";
SQLiteDatabase db = this.getWritableDatabase();
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
for(int idx=0; idx < Produc_List.size(); idx++) {
statement.clearBindings();
statement.bindLong(1, Produc_List.get(idx).getProduct_id());
statement.bindLong(2, Produc_List.get(idx).getCategory_id());
statement.bindString(3, Produc_List.get(idx).getName());
// statement.bindString(4, Produc_List.get(idx).getBrand());
statement.bindString(5, Produc_List.get(idx).getPrice());
//statement.bindString(6, Produc_List.get(idx).getDiscPrice());
statement.bindString(7, Produc_List.get(idx).getImage());
statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
statement.bindLong(9, Produc_List.get(idx).getPl_rank());
statement.execute();
}
db.setTransactionSuccessful();
db.endTransaction();