更新时获取行 ID

Get row id on update

假设我有一个具有以下结构的 table:

| name        | Type          |
| ----------- |:-------------:|
| id          | primary       |
| word        | unique        |
| frequency   | integer       |

对于这个table,我正在插入,当出现重复时,我会更新频率列。伪代码看起来像这样:

try {
    INSERT into WORDLIST word1
    id = lastInsertedId
} catch(Exception) {
    //if a duplicate happens
    UPDATE wordlist WHERE word = "word1"
    id = SELECT id FROM wordlist where word = "word1"
}
//save the updated/inserted id somewhere

上面代码的问题是,当发生重复时,我被迫执行额外的 select 查询来获取更新行的 id,这是一个性能破坏者,并且会减慢应用程序大约30%.

我对其他方法持开放态度,但想不出比这种 try/catch 带有额外查询的方法更好的方法

UPDATE 语句不能return 数据。如果需要ID,需要运行一个SELECT.

请注意,任何 INSERT 或 UPDATE 都必须检查 word 列是否有重复项,因此 SELECT 将从缓存中完全 运行。任何减速都可能来自 运行 自动事务的多项更改。

另外,依靠异常来检测重复,如果有其他错误就会崩溃。最好先检查重复项(由于上述原因,这不会降低效率):

BEGIN;
SELECT id FROM wordlist WHERE word = ?;
if found:
    UPDATE wordlist ... WHERE id = ?;   -- faster than word=?
else:
    INSERT INTO wordlist;
COMMIT;

由于 word 已经有一个唯一索引,您可以尝试使用 insert or replace:

来简化您的查询
INSERT OR REPLACE into WORDLIST word1
id = last_insert_rowid()

请注意,在冲突情况下,会创建一个新的 rowid/ID 并删除旧的。如果您需要保留 ID,您可以求助于使用触发器,这可能比在应用程序代码中处理特殊情况执行得更好。

如果您只想实现一个点击计数器,您可以查看以下答案: