为啥 UPSERT 执行 DELETE 和 INSERT 而不是 UPDATE (SQLite)
Posted
技术标签:
【中文标题】为啥 UPSERT 执行 DELETE 和 INSERT 而不是 UPDATE (SQLite)【英文标题】:Why does UPSERT does a DELETE and INSERT instead of UPDATE (SQLite)为什么 UPSERT 执行 DELETE 和 INSERT 而不是 UPDATE (SQLite) 【发布时间】:2015-03-23 16:12:32 【问题描述】:我想知道为什么至少在使用 Peewee 时,当条目已经在表中时,UPSERT 会执行 DELETE 和 INSERT 而不是 UPDATE?
有什么理由比“删除然后插入”而不是“尝试更新,否则插入”更可取?
UPDATE 是否比 DELETE & INSERT 更耗时?还是 UPSERT 真的是一个 INSERT(force=True) 查询?
【问题讨论】:
我不认为 SQLite 支持 UPSERT.. 没有关于它的文档:sqlite.org/docs.html 我的错。显然该层是由 Peewee 处理的。 Juste编辑了这个问题。但是,从我读过的内容来看,这似乎是一个常见的实现。 可能是更新中的数据占用空间较大,无法就地更新。 @BeNdErR,SQLite 通过INSERT OR REPLACE INTO
支持UPSERT。 @bsuire,peewee 不会“伪造”一个 upsert。如果数据库支持,则会发出原生 upsert,否则会收到错误消息。
【参考方案1】:
我想知道为什么至少在使用 Peewee 时,当条目已经在表中时,UPSERT 会执行 DELETE 和 INSERT 而不是 UPDATE?
Peewee 没有明确地先删除然后插入。如果您使用的是 SQLite,它确实支持 upsert,那么 peewee 将发出:
INSERT OR REPLACE INTO <table> ...
这就是 peewee 实现 upsert 的方式。 Peewee 本身不会发出单独的 DELETE 语句。
见https://www.sqlite.org/lang_replace.html
【讨论】:
【参考方案2】:这不是更好吗:
UPDATE t SET a = 'pdf' WHERE id = 2;
INSERT INTO t(id, a) SELECT 2, 'pdf' WHERE changes() = 0;
如果更新失败,则更改()=0,因此它会进行插入。
【讨论】:
以上是关于为啥 UPSERT 执行 DELETE 和 INSERT 而不是 UPDATE (SQLite)的主要内容,如果未能解决你的问题,请参考以下文章
为啥work bench 执行不了mysql delete语句
C语言中已经有了malloc和free,为啥还需要new和delete?
c++(在类中)执行buf=new char[i];delete []buf; 为啥没有调用构造和析构函数?