私は常に実行され、いくつかのメッセージを受信するアプリケーションを持っています(それらの速度は毎秒数回から毎時なしまで変化します)。すべてのメッセージはSQLiteデータベースに入れる必要があります。これを行うための最良の方法は何ですか?
各メッセージでデータベースを開いたり閉じたりするのはよくありません。1秒間に数十のメッセージがあると、非常に遅くなります。
一方、データベースを一度開いて書き込みを行うだけで、プロセスが予期せず終了した場合にデータが失われる可能性があります。
私は常に実行され、いくつかのメッセージを受信するアプリケーションを持っています(それらの速度は毎秒数回から毎時なしまで変化します)。すべてのメッセージはSQLiteデータベースに入れる必要があります。これを行うための最良の方法は何ですか?
各メッセージでデータベースを開いたり閉じたりするのはよくありません。1秒間に数十のメッセージがあると、非常に遅くなります。
一方、データベースを一度開いて書き込みを行うだけで、プロセスが予期せず終了した場合にデータが失われる可能性があります。
何をするにしても、トレードオフを行う必要があります。
安全性が最優先事項である場合は、各メッセージのデータベースを更新して、スピードを上げてください。
妥協が必要な場合は、データベースを更新して、非常に多くのメッセージを書き込みます。たとえば、バッファを維持し、100番目のメッセージごとに、トランザクションにラップされた更新を発行します。
トランザクションのラッピングは、2つの理由で重要です。まず、速度を最大化します。第二に、ロギングを使用する場合、エラーからの回復に役立ちます。
上記のバッチ更新を行う場合は、ファイルに届く各メッセージをログに記録することで、安全性をさらに高めることができます。データベースの更新が正常に発行されるたびに、このログをリセットします。そうすれば、更新が失敗した場合、(トランザクションを使用しているため)ブロック全体で失敗したことがわかり、ログには更新されなかった情報が含まれます。これにより、更新を再発行したり、失敗の原因となったデータに問題があったかどうかを確認したりすることができます。もちろん、これは、ログを保持する方がデータベースを更新するよりも安価であることを前提としています。これは、接続方法によってはそうなる可能性があります。
アプリケーションの動作をメッセージレートに合わせて調整する簡単なアルゴリズムがあります。
このようにして、メッセージレートが高くなりすぎない限り、すべてのメッセージがすぐに保存されます。
注:データベースを閉じても、データの耐久性は向上しません(これがトランザクションコミットの目的です)。メモリを少し解放するだけです。
トップレートが「1秒あたり数回」の場合、データベースの開閉に実際の問題は見られません。これは、サーバーに障害が発生した場合にデータをすぐに記録することが重要な場合に特に当てはまります。
レポート製品ではSQLiteを使用しており、これまでに確認できた最高のパフォーマンスは、一度に数千のブロックで行を記録することです。デフォルトの設定は約50kです。つまり、アプリは5万行のデータが収集されるまで待機し、それを1つのトランザクションとしてコミットします。