I've been using MySQL for some time now, but plan to move to PostgreSQL in the semi-near future, so I am trying to make my SQL as compliant as possible.
MySQL's "REPLACE INTO" is not compliant. I am currently using MyISAM tables instead of InnoDB, so transactions are out of the question.
Here are four alternatives off the top of my head (in pseudocode):
method 1: select ? update : insert;
method 2: if (!update) { insert; }
method 3: if (!insert) { update; }
method 4: if (select) { delete; } insert;
method 4 is how "REPLACE INTO" works, but methods 2 and 3 use one less query and I am trying to minimize the # of queries per page execution.
The problem is that the first 3 are subject to race conditions, and #4 would require extra care to ensure key integrity (especially in auto_increment tables)
I have used method#2 in a couple places, but unfortunately have ended up with some duplicate records. This has only happened in my traffic logging code so I figure two people with the same user_agents hit the site at the same time and both "!update" checks occured concurrently so they both inserted.
I would think #3 would be less succeptable to race conditions because it would be very unlikely that the record would be deleted between "!insert" check and the update. In fact, with rare exception, traffic records are never cleared (but I may have some sort of archiving system in the future).
I use #1 in some places, but it is a little clunky (like #4) and shares the same weakness as #3.
Are there other methods that I am not thinking of? I am trying to avoid MySQL-specific tricks such as "ON DUPLICATE KEY ..."
If there are no other better methods, which do you think is best? Performance is not nearly as much of an issue as the race conditions.
Thank you for your time.