2017-10-03 8 views
0

J'ai une table avecPrévenir Incrémentation automatique Sauter sur clé en double mise à jour

(ID INT auto_incrment primary key, 
tag VARCHAR unique) 

Je veux insérer plusieurs balises à un. Comme ceci:

INSERT INTO tags (tag) VALUES ("java"), ("php"), ("phyton"); 

Si j'exécuterait cela, et « java » est déjà dans la table, je me fais une erreur. Il n'ajoute pas "php" et "phyton".

Si je le fais comme ceci:

INSERT INTO tags (tag) VALUES ("java"), ("php"), ("phyton") 
    ON DUPLICATE KEY UPDATE tag = VALUES(tag) 

il est ajouté sans erreur, mais il saute 2 valeurs au champ ID.

Exemple: J'ai Java avec ID = 1 et je lance la requête. Alors PHP sera 3 et Phyton 4. Existe-t-il un moyen d'exécuter cette requête sans ignorer les ID?

Je ne veux pas de grands espaces entre eux. J'ai également essayé INSERT IGNORE.

Merci!

+0

Alors que vous devriez NTO veiller à ce que beaucoup de valeurs continues, si vous voulez changer ce comportement, vous pouvez définir 'innodb_autoinc_lock_mode = 0' dans votre fichier de configuration, voir par exemple [Incrémenter automatiquement les numéros?] (Https://stackoverflow.com/q/17798835/6248528) Mais attention aux effets secondaires potentiels (et aux cas qu'il couvre), lisez donc le lien vers le manuel dans cette réponse. Vous devez disposer des autorisations pour modifier la configuration du serveur. Sinon, vous pouvez calculer le numéro suivant manuellement lorsque vous insérez (vous ne pouvez donc pas utiliser la fonction d'auto-incrémentation) ou cesser de vous soucier des interruptions. – Solarflare

Répondre

0

Voir "SQL # 1" dans http://mysql.rjweb.org/doc.php/staging_table#normalization. Il est plus complexe mais évite les identifiants «brûlants». Il a l'inconvénient potentiel d'avoir besoin des balises dans une autre table. Un extrait de ce lien:

# This should not be in the main transaction, and it should be 
# done with autocommit = ON 
# In fact, it could lead to strange errors if this were part 
# of the main transaction and it ROLLBACKed. 
INSERT IGNORE INTO Hosts (host_name) 
    SELECT DISTINCT s.host_name 
     FROM Staging AS s 
     LEFT JOIN Hosts AS n ON n.host_name = s.host_name 
     WHERE n.host_id IS NULL; 

En isolant ce que sa propre transaction, nous obtenons fini pressé, réduisant ainsi le blocage. En disant IGNORE, on se fiche que d'autres threads insèrent 'simultanément' les mêmes host_names. (Si vous ne disposez pas d'un autre thread faire comme INSERTs, vous pouvez lancer la IGNORE.)

(Ensuite, il continue de parler IODKU.)