MySQL "bonne" façon d'insérer une ligne si elle n'est pas trouvée, ou le mettre à jour si elle est trouvée

Très souvent, j'ai envie d'exécuter une requête sur un de mes utilisateurs où je veux une ligne stockée et associées à cet utilisateur, dans un 1-de-1 de la relation. Donc, disons (c'est juste un exemple au hasard), que j'ai une table qui garde la trace d'un utilisateur de la voiture, avec quelques infos sur la voiture. Chaque utilisateur peut avoir 0 ou 1 voitures. Si l'utilisateur n'a pas de voiture, il n'y a aucune entrée dans la table pour cet utilisateur.

table de voitures (de nouveau, juste un exemple):
id, user_id, car_make, car_model

Donc, quand j'ai mise à jour de ce tableau, je finis toujours par faire quelque chose comme ceci (pseudo-code):

result = SELECT * FROM cars WHERE user_id=5
if (num_rows(result)>0){
    UPDATE cars SET car_make='toyota', car_model='prius' WHERE user_id=5
}else{
    INSERT INTO cars (user_id, car_make, car_model) VALUES (5, 'toyota', 'prius')
}

Comment puis-je faire cela dans un élégant déclaration de travaux "automatiquement"? Qu'advient-il si, dans un autre processus, la ligne est SUPPRIMÉE entre le SELECT et UPDATE? Mon instruction de mise à JOUR échoue où l'instruction INSERT devriez avoir exécuté. Et je sens que j'ai besoin de faire deux semblables (mais différentes) instructions pour accomplir la même chose! Ce que j'ai besoin est une déclaration qui va m'assurer que les données que je veux existe dans la table, surtout lorsque je veux seulement 1 ligne qui répond à mes besoins. Par exemple, il pourrait être quelque chose comme (ce qui est totalement composée de cours):

MAKE SURE A ROW IN cars WHERE user_id=5 IS SET WITH car_make='toyota', car_model='prius'

De cette façon, si user_id de 5 existe déjà, il sera mis à jour, sinon, il sera inséré. Aussi, si j'ai changé les exigences, par exemple-à-dire que chaque utilisateur peut avoir zéro, un ou une des voitures de car_make, alors je pourrais préciser que:

MAKE SURE A ROW IN cars WHERE user_id=5 AND car_make='toyota' IS SET WITH car_model='prius'

J'espère que ma question a du sens! Comment puis-je améliorer cette base insérez-si-pas-de trouver ou de mettre à jour-si-trouvé opération qui vient si souvent? Merci pour toute aide!

source d'informationauteur DivideByHero