MySQL on duplicate key update detailed

Source: Internet
Author: User

Have you ever encountered this scenario in our daily development: to see if a record exists, to create a new record if it doesn't exist, to update some fields if it exists. Is your approach just as follows?

$result = mysql_query(‘select * from xxx where id = 1‘);$row = mysql_fetch_assoc($result);if($row){mysql_query(‘update ...‘);}else{mysql_query(‘insert ...‘);}

There are a few drawbacks to this notation:

    • A small amount of performance consumption. Executed two times SQL, followed by a SQL one to two times the network transmission, then this is 4 times.
      Trouble A very simple logical lack to write ten lines of code.
    • There is a problem with high concurrency. For example, when we obtain the required data, before the update, there is another request just delete the record, our update operation does not play a role, or, if we have a problem in the way of updating the operation, such as updating column A, we use a = $row[a] + 1 instead of a = a +1 this atomic operation, It is possible that the field has been modified by another request, resulting in an error in the data.

Fortunately, MySQL takes this into account, providing the syntax that, when an insert is made insert … on duplicate key update , if the insert data causes a unique index (including the primary key index) to conflict, that is, if the unique value is duplicated, the insert operation is not performed and the subsequent update operation is performed.

For example, there is now a table test,test table with field A, a primary key or a unique index on a, and only one a=1 in the table, b=1 data, now execute the following sql:

insert into test (a,b) values (1,2) on duplicate key update b = b = 1;#因为a=1的记录已存在了,所以不会执行insert,而会在该条记录上执行update语言`b=b+1`,记录会变成a=1,b=2insert into test (a,b) values (2,2) on duplicate key update b = b + 1;#a=2的记录不存在,所以执行insert

This way we don't have to judge the existence of records in the application, nor do we need to be in a situation where the data goes wrong in high concurrency.

If the row is inserted as a new record, the affected behavior is 1, and if the original record is updated, the affected behavior is 2, and if the original record already exists, but the updated value and the original value are the same, the affected behavior is 0.

Multiple Unique index conflicts

For testing convenience, we have built the following data sheet:

create table test(a int not null primary key,b int not null UNIQUE key,c int not null)

To test the case where two unique indexes are conflicting, insert the following data:

insert into test values(1,1,1), (2,2,2);

Then execute:

insert into test values(1,2,3) on duplicate key update c = c + 1;

Because both A and B are unique indexes, the inserted data creates a conflict on two records, but only the first record is modified after execution:

mysql> select * from test;+---+---+---+| a | b | c |+---+---+---+| 1 | 1 | 2 || 2 | 2 | 2 |+---+---+---+2 rows in set (0.00 sec)

The above statement is equivalent to:

update test set c=c+1 where a=1 or b = 2 limit 1;

If a=1 or b =2 more than one record is matched, only the first record is updated. So, in general, we should avoid using tables with multiple unique indexes on duplicate key update .

Use the values () method

You can use methods in update to values() reference values in the insert, such as:

insert into test values(1,3,5) on duplicate key update c = values( c )+ 1;

This statement updates the value of the C field in the A=1 record to 6 because the value of values (c) is the value of the insert portion of the reference, which in this case is insert into test values(1,3,5)  5, so the value of the final update is 6.

LAST_INSERT_ID ()

insert … on duplicate key update last_insert_id() Returns the value of the Auto_increment field if the table contains a auto_increment field, using Insert or update.

concurrency control

When used on a partitioned table with table-level locks such as MyISAM insert … on duplicate key update , all partitioned tables are locked, and all partitioned tables are not locked on partition tables such as row-level locks that use InnoDB.

Delayed options

The delayed option is ignored when we use the on duplicate key update.

MySQL on duplicate key update detailed

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.