更新时获取行 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,您可以求助于使用触发器,这可能比在应用程序代码中处理特殊情况执行得更好。
如果您只想实现一个点击计数器,您可以查看以下答案:
假设我有一个具有以下结构的 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,您可以求助于使用触发器,这可能比在应用程序代码中处理特殊情况执行得更好。
如果您只想实现一个点击计数器,您可以查看以下答案: