获取更新时的行ID

时间:2017-08-25 20:17:39

标签: sqlite upsert

假设我有一个以下结构的表格:

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

对于这个表,我正在进行插入,当发生重复时,我将更新频率列。伪代码看起来像这样:

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

上面代码的问题在于,当重复发生时,我被迫做一个额外的选择查询来获取更新行的id,这是一个性能破坏者,并将应用程序减慢约30%。

我对其他方法持开放态度但是没有想到比使用额外查询的try / catch方法更好的方法

2 个答案:

答案 0 :(得分:0)

UPDATE语句无法返回数据。如果您需要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;

答案 1 :(得分:0)

由于word已有唯一索引,您可以尝试使用insert or replace来简化查询:

INSERT OR REPLACE into WORDLIST word1
id = last_insert_rowid()

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

如果您想要的只是实现点击计数器,您可以查看以下答案:https://stackoverflow.com/a/42556302/5794048