SQLite の UPSERT 機能を理解する
INSERT と UPDATE を組み合わせた UPSERT 操作は、必要に応じて既存のレコードを更新したり、新しいレコードを挿入したりすることで、データの変更を効率的に処理します。 SQLite は UPSERT を直接サポートしていますが、部分的な更新での使用を最適化するには慎重な検討が必要です。
SQLite の UPSERT 構文
SQLite バージョン 3.24.0 で導入された ON CONFLICT
句により、正確な UPSERT 制御が可能になります。 例:
<code class="language-sql">INSERT OR REPLACE INTO table (id, name) VALUES (1, 'John Foo') ON CONFLICT(id) DO UPDATE SET name = 'John Foo';</code>
一致する name
を持つレコードが存在する場合、これにより id
フィールドが更新されます。それ以外の場合は、新しい行が挿入されます。
部分的なアップデートへの対応
部分的な更新の管理 (特定の列のみを変更し、他の列はそのままにする) には課題があります。 次のシナリオを考えてみましょう。Blob1
と Blob2
を更新しますが、レコードが存在する場合は Blob3
を変更しないままにしておきます。そうでない場合は、Blob3
を NULL に設定します。
効率的な部分更新ソリューション
ON CONFLICT
句は、洗練されたソリューションを提供します。
<code class="language-sql">INSERT INTO table (id, Blob1, Blob2, Blob3) VALUES (1, 'Data1', 'Data2', NULL) ON CONFLICT(id) DO UPDATE SET Blob1 = 'Data1', Blob2 = 'Data2';</code>
このアプローチでは、競合 (Blob1
と一致) が発生した場合に、Blob2
と id
のみが更新されます。 重要なのは、レコードが存在しない場合、INSERT
は指定どおりに Blob3
を NULL に設定することです。
代替方法 (効率が低い)
または、SELECT
と REPLACE
の組み合わせでも同じ結果が得られます。
<code class="language-sql">SELECT name INTO @name FROM Employee WHERE id = 1; REPLACE INTO Employee (id, role) VALUES (1, 'code monkey', @name);</code>
これは、事前に読み込むことで元の name
値を保存します。ただし、この方法では一般に、ON CONFLICT
アプローチと比較してオーバーヘッドが増加します。
以上がSQLite の UPSERT は部分的な更新と挿入をどのように効率的に処理するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。