SQLiteデータベースで同時書き込みが許可されないのはなぜですか?


79

SQLiteでJavaを使用してデータベースプログラミングを行っています。

データベースへの一度に1つの接続のみが書き込み機能を持ち、多くの接続が一度に読み取り機能を持つことがわかりました。

SQLiteのアーキテクチャがなぜこのように設計されたのですか?書き込まれている2つのものがデータベース内の同じ場所に書き込まれていない限り、なぜ2つの書き込みが一度にできないのですか?



5
SQLiteは「ライト」として設計されているためです。パフォーマンスのある低メモリおよび低処理。SQLiteに同じファイルへの複数の書き込みを処理させる方法を検討してください。現在の設計は簡単に実装できます。ファイル全体がロックされ、他のユーザーは待機する必要があります。より低い粒度で書き込みの並行性を処理するには、RDMSから取得する行/ページのロックが必要です。要件が書き込みの同時実行性を要求する場合、SQLiteは候補ではなく、代わりに軽量のRDBMSを参照する必要があります。en.wikipedia.org
Thomas Carlisle

回答:


157

「複数の同時書き込み」は、シングルライター、マルチリーダーよりもコアデータベースエンジンで達成するのがはるかに難しいためです。SQLiteの設計パラメーターを超えており、それを含めると、SQLiteの非常に小さいサイズと単純さを覆す可能性があります。

高度な書き込み同時実行性のサポートは、DB2、Oracle、SQL Server、MySQL、PostgreSQL、NonStop SQL、Sybaseなどの大規模データベースエンジンの特徴です。しかし、達成するのは技術的に困難であり、データベース、テーブル、行のロックなどの広範な同時実行制御と最適化戦略、または最新の実装では複数バージョンの同時実行制御が必要です。この問題/要件に関する研究は膨大で、数十年前に遡ります。

SQLiteの設計哲学は、複数のライターをサポートするほとんどのサーバー中心のDBMSとはまったく異なります。SQLとリレーショナルモデルの力を個々のアプリケーションにもたらし、実際に各アプリケーションに組み込むことができるように設計されています。その目標には大きなトレードオフが必要です。複数の同時ライターを処理するために必要な重要なインフラストラクチャとオーバーヘッドを追加しないこともその1つです。

この哲学は、SQLiteの適切な使用ページのステートメントで要約できます。

SQLiteは、クライアント/サーバーデータベースと競合しません。SQLiteはfopen()と競合します。


41
+1。SQLiteはインプロセスデータベースです。サーバーベースのDBにあるような中央のアービターはありません。作家は直接協力し、お互いを信頼しなければなりません。1人の悪意のある作家が協力しないだけで大混乱を引き起こす可能性があります。
ヨルグWミッターグ

12
また、SQLiteを実行する環境の中には、複数のプロセスをサポートしていないものもあります。
-david25272

1
おそらく、悪意のある書き込みは、協力しないことですでに大混乱を引き起こす可能性があります。SQLiteコードを使用してそれを行うことはできませんが、独自のコードを持つことができます。これは、unlink()の呼び出しである可能性があります
-bdsl

12
並行アプリでは、多くの妥協点はありません。困難な状況やエッジケースを含め、ほぼ100%の時間で並行性、一貫性、およびデータの整合性を得ることができますが、そうでない場合もあります。そうしないと、壊れやすく、遅く、クラッシュしやすく、人々はすぐにそれを信頼しなくなります。しかし、それを定期的に正しくすることは、非常に困難です。コアサポートがほとんどないライターが、インターリーブされた書き込みを自分で調整できる状況はそれほど多くありません。
ジョナサンユニス

8
@bdslあらゆる種類のデータベースは、ライター行儀が悪く、データを失わないことを想定する必要があります。著者のSQLiteは、それをの競合他社として位置付けてfopen()いるため、プレーンテキストファイルへの同時書き込みに伴うすべての毛羽立ちを考慮してください。
Blrfl

12

物事を同じ場所に書き込むかどうかを判断できるサーバーがないためです。ファイルに書き込もうとするプロセスは2つだけです。

コメントで指摘したように、同時書き込みは内部スレッドでもサポートできます。これがどれだけうまく機能するかはわかりません(それについてもあまり考えませんでした)。とにかく、SQLiteがスレッドを使用しない理由は次のとおりです。Hipp博士はスレッドが悪だと考えています。

DR Hippがスレッドを悪であると考えているという事実は、SQLite FAQに文書化されています。


2
これは、同時書き込みが許可されない技術的な理由を説明しますが、設計上の決定が下された理由ではありません。
ロバートハーヴェイ

3
SQLiteが一度に1つの書き込みのみを処理するように設計する決定。
ロバートハーヴェイ

7
@Goyoサーバーは、同時書き込みを処理する必要はありません。データベースサーバーが別個のプロセスであるのと同じように、SQLiteの内部に同じ目的で機能する別個のスレッドが存在する可能性があります。Robert Harveyは正しい。SQLiteチームが設計上の決定を下したが、単一のライブラリが同時書き込みを処理する能力とは何の関係もない(理論的には可能であるため)。

1
この答えは私にはいいようです。同時書き込みを処理するには、サーバーまたはマルチスレッドsqlite実装のいずれかが必要と思われます。どちらも他の設計上の決定によって除外されているため、同時書き込みの実装は非常に困難です。
jpa

5
@jpa:SQLiteは、「サーバー」なしで複数のプロセス/スレッド間でロックを同期します。「サーバー」は必要ありません。OSが提供するロック/同期/ IPC /その他を使用すれば十分ですが、複雑になります。投稿で言及されている「内部スレッド」は意味をなしません。
マット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.