MySQL有这样的东西:
INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;
据我所知,SQLite中不存在此功能,我想知道的是,是否有任何方法可以实现相同的效果而不必执行两个查询。另外,如果这不可能,那么您更喜欢什么:
- SELECT +(插入或更新)或
- UPDATE(如果UPDATE失败,则 + INSERT )
MySQL有这样的东西:
INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;
据我所知,SQLite中不存在此功能,我想知道的是,是否有任何方法可以实现相同的效果而不必执行两个查询。另外,如果这不可能,那么您更喜欢什么:
Answers:
因为3.24.0 SQLite还支持upsert,所以现在您可以简单地编写以下内容
INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON CONFLICT(ip) DO UPDATE SET hits = hits + 1;
INSERT OR IGNORE INTO visits VALUES ($ip, 0);
UPDATE visits SET hits = hits + 1 WHERE ip LIKE $ip;
这要求“ ip”列具有UNIQUE(或PRIMARY KEY)约束。
编辑:另一个很好的解决方案:https : //stackoverflow.com/a/4330694/89771。
REPLACE
不是一种选择。
我更喜欢UPDATE (+ INSERT if UPDATE fails)
。更少的代码=更少的错误。
当前答案仅在sqlite OR mysql中有效(取决于您是否使用OR)。因此,如果您希望跨dbms兼容性,则可以执行以下操作:
REPLACE INTO `visits` (ip, value) VALUES ($ip, 0);
REPLACE
也可以在SQLite上使用,但是在MySQL上,它将始终将计数器重置为0-尽管查询是可移植的,但最终结果会相差很多。
您应该为此使用memcached,因为它是存储单个值(访问次数)的单个键(IP地址)。您可以使用原子增量功能来确保没有“竞赛”条件。
它比MySQL更快,并且节省了负载,因此MySQL可以专注于其他事情。
upsert
在一个事务中(例如使用Pythonexecutemany()
函数)执行多个这样的操作?