2017-01-02 4 views
1

私のプログラムで編集するはずの膨大なファイルを想像してみてください。読み込み時間を長くするために、mmap()を使い、私が見ている部分だけを読み上げます。しかし、ファイルの途中に行を追加したい場合、そのための最良の方法は何ですか?sqlite3はどのように大きなファイルを編集しますか?

行を追加して残りのファイルを移動する唯一の方法はありますか?それは高価に聞こえる。

私の質問は基本的には何ですか:巨大なファイルの途中でデータを追加する最も効率的な方法は何ですか?

この質問は以前ここに頼まれた:答えは、直接ファイルのsqlite3のisteadを使用することをお勧め How to edit a big file

を。それは私が不思議に思う、どのようにsqlite3はこの問題を解決するのですか?

答えて

1

SQLiteはリレーショナルデータベースです。主な編集手段はbtreeテーブルとbtreeインデックスです。 BTreesは、レコードが増えても編集されるように設計されています。さらに、SQLiteはファイルを保存している間にクラッシュから回復するために.journalファイルを使用します。

BTreesは、プライマリキーまたはインデックス付きの列によるレコードのログ(N)検索時間のみを支払う(ログベースが大きいためレコードをソートするよりもはるかに高速です)。 BTreesはブロックポインタをほとんどどこでも使用するため、順序リストの中程は比較的簡単に更新できます。

RichNが指摘するように、SQLiteはファイル内に無駄なスペースを構築します。 VACUUMを定期的に実行して解放します。

ちなみに私は手でBTreesを書いています。彼らは書くべき痛みですが、あなたが何らかの理由で必要としているなら価値があります。

0

SQLiteデータベースファイルの内容は、これらのレコードにアクセスするためのレコードとデータ構造で構成されています。 SQLiteは未使用部分とともにファイルの使用部分を追跡します(レコードが削除されたときに利用可能になります)。新しいレコードを追加して未使用セグメントに収まると、その位置になります。それ以外の場合は、ファイルに追加されます。インデックスは、新しいデータを指すように更新されます。索引を更新することにより、さらに索引レコードを追加することができる。 SQLite(とデータベースマネージャー)は、新しいレコードを挿入するときにはコンテンツを移動しません。

時間が経つにつれて、内容はディスク全体に分散します。シーケンシャルレコードは互いに近くに配置されず、一部のクエリのパフォーマンスに影響する可能性があります。

SQLite VACUUMコマンドは、ファイル内の未使用領域を削除したり、データ内のローカリティの問題を修正したりすることができます。 VACUUM Command

関連する問題