SQLite INSERT – OP DUPLICATE KEY UPDATE (UPSERT)

MySQL heeft zoiets als dit:

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;

Voor zover ik weet bestaat deze functie niet in SQLite, wat ik wil weten is of er een manier is om hetzelfde effect te bereiken zonder twee query’s uit te voeren. En als dit niet mogelijk is, wat heeft uw voorkeur:

  1. SELECT + (INSERT of UPDATE)of
  2. UPDATE (+ INSERT als UPDATE mislukt)

Antwoord 1, autoriteit 100%

INSERT OR IGNORE INTO visits VALUES ($ip, 0);
UPDATE visits SET hits = hits + 1 WHERE ip LIKE $ip;

Hiervoor moet de kolom ‘ip’ een UNIEKE (of PRIMAIRE SLEUTEL) beperking hebben.


EDIT: Nog een geweldige oplossing: https://stackoverflow.com/a/4330694/89771.


Antwoord 2, autoriteit 39%

Sinds 3.24.0 ondersteunt SQLite ook upsert, dus nu kun je eenvoudig het volgende schrijven

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON CONFLICT(ip) DO UPDATE SET hits = hits + 1;

Antwoord 3, autoriteit 16%

Ik heb liever UPDATE (+ INSERT if UPDATE fails). Minder code = minder bugs.


Antwoord 4, autoriteit 6%

Het huidige antwoord werkt alleen in sqlite OR mysql (afhankelijk van of je OR gebruikt of niet). Dus, als je cross dbms-compatibiliteit wilt, is het volgende voldoende…

REPLACE INTO `visits` (ip, value) VALUES ($ip, 0);

Antwoord 5

U moet hiervoor memcached gebruiken, aangezien het een enkele sleutel (het IP-adres) is die een enkele waarde (het aantal bezoeken) opslaat. U kunt de functie voor atomaire toename gebruiken om te verzekeren dat er geen “ras”-omstandigheden zijn.

Het is sneller dan MySQL en bespaart de belasting, zodat MySQL zich op andere dingen kan concentreren.

Other episodes