mysql 不存在则插入

Posted RainDream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 不存在则插入相关的知识,希望对你有一定的参考价值。

主要看在事务中不存在则插入的阻塞情况。

表定义:

mysql> desc user;
+-------------+------------------+------+-----+-------------------+----------------+
| Field       | Type             | Null | Key | Default           | Extra          |
+-------------+------------------+------+-----+-------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
| name        | varchar(50)      | NO   | MUL | NULL              |                |
| password    | char(20)         | NO   |     | NULL              |                |
| regist_time | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
+-------------+------------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

client1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user;
+----+------+----------+---------------------+
| id | name | password | regist_time         |
+----+------+----------+---------------------+
|  1 | a    | a        | 2018-03-11 16:32:43 |
|  2 | b    | b        | 2018-03-11 16:33:09 |
|  3 | c    | c        | 2018-03-11 16:33:39 |
+----+------+----------+---------------------+
3 rows in set (0.00 sec)

mysql> insert into user(name,password) select ‘d‘,‘d‘ from dual where not exist (select name from user where name=‘d‘);
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0 mysql
> select * from user; +----+------+----------+---------------------+ | id | name | password | regist_time | +----+------+----------+---------------------+ | 1 | a | a | 2018-03-11 16:32:43 | | 2 | b | b | 2018-03-11 16:33:09 | | 3 | c | c | 2018-03-11 16:33:39 | | 4 | d | d | 2018-03-11 17:03:35 | +----+------+----------+---------------------+ 4 rows in set (0.00 sec)

然后启动client2:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user;
+----+------+----------+---------------------+
| id | name | password | regist_time         |
+----+------+----------+---------------------+
|  1 | a    | a        | 2018-03-11 16:32:43 |
|  2 | b    | b        | 2018-03-11 16:33:09 |
|  3 | c    | c        | 2018-03-11 16:33:39 |
+----+------+----------+---------------------+
3 rows in set (0.00 sec)

mysql> select * from user where name=d;
Empty set (0.02 sec)

mysql> insert into user (name,password) select d,d from dual where not exists (select name from user where name=d);

client2 执行“ insert into user (name,password) select ‘d‘,‘d‘ from dual where not exists (select name from user where name=‘d‘); ”出现阻塞,直到超时或client1 commit。

client2 直接执行插入操作则不会阻塞:

mysql> insert into user(name, password) values (d,d);
Query OK, 1 row affected (0.00 sec)

client2 执行:

mysql> insert into user (name,password) select e,e from dual where not exists (select name from user where name=e);

也会出现阻塞,可见,这种情况使用的是表锁。另:如果已经存在name=‘d‘的数据,client1执行"insert not exists"后并不会使用表锁,client2执行时不会阻塞。

client1 查询后commit:

mysql> select * from user;
+----+------+----------+---------------------+
| id | name | password | regist_time         |
+----+------+----------+---------------------+
|  1 | a    | a        | 2018-03-11 16:32:43 |
|  2 | b    | b        | 2018-03-11 16:33:09 |
|  3 | c    | c        | 2018-03-11 16:33:39 |
|  4 | d    | d        | 2018-03-11 17:03:35 |
+----+------+----------+---------------------+
4 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.04 sec)

client2 查询后commit:

mysql> select * from user;
+----+------+----------+---------------------+
| id | name | password | regist_time         |
+----+------+----------+---------------------+
|  1 | a    | a        | 2018-03-11 16:32:43 |
|  2 | b    | b        | 2018-03-11 16:33:09 |
|  3 | c    | c        | 2018-03-11 16:33:39 |
|  5 | d    | d        | 2018-03-11 17:36:16 |
+----+------+----------+---------------------+
4 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.04 sec)

注意client1 和 client2 name=‘d‘的id。

 

另:on duplicate key只适用于unique key,如果不是unique,总是会插入

mysql> insert into user(name,password) values(d,d) on duplicate key update password=e;

这时会插入一条name=‘d‘,password=‘d‘的记录。


以上是关于mysql 不存在则插入的主要内容,如果未能解决你的问题,请参考以下文章

mysql插入数据时,判断是不是存在,存在则替代,不存在则直接插入,需要能够批量处理。

Mysql插入数据:不存在则插入,存在则跳过或更新

MySQL INSERT插入条件判断:如果不存在则插入

MySQL:数据存在则更新,不存在则插入

mysql 不存在则插入

mysql批量更新,数据存在则更新,不存在则插入