传统做法
先查询数据、再判断是否存在,存在则执行更新,不存在则执行插入。
传统做法存在的问题
- 并发请求可能会出现数据重复插入
- 效率低
- 无法保证数据的唯一性
- 代码量比较大
使用MySQL唯一索引
接下来演示如何通过 MySQL 唯一索引实现存在则更新、不存在则插入。创建测试表
创建 progress 进度表,要求 resource_id 不能重复,使用unique index (resource_id)
声明唯一索引。
如果建表的时候没有创建唯一索引,后期也可以通过语句创建唯一索引:create table progress (
progress_id bigint unsigned auto_increment primary key,
resource_id bigint unsigned not null comment '环节id',
rate decimal(8, 2) default 0 not null comment '进度百分比(0~100)',
unique index (resource_id)
) comment '进度表';
create unique index progress_uindex on progress (resource_id)
测试插入数据
插入数据,成功: ```sql mysql> insert into progress(resource_id, rate) VALUES (1, 50); Query OK, 1 row affected (0.01 sec)
mysql> select * from progress; +——————-+——————-+———-+ | progress_id | resource_id | rate | +——————-+——————-+———-+ | 5 | 1 | 50.00 | +——————-+——————-+———-+ 1 row in set (0.00 sec)
尝试插入重复数据,报错,可以看到唯一索引起作用了:
```sql
mysql> insert into progress(resource_id, rate) VALUES (1, 50);
ERROR 1062 (23000): Duplicate entry '1' for key 'progress.resource_id'
测试存在则更新、不存在则插入
使用 MySQL 的 on duplicate key update
语句实现:
mysql> insert into progress(resource_id, rate) VALUES (1, 100) on duplicate key update rate = 100;
Query OK, 2 rows affected, 1 warning (0.00 sec)
mysql> select * from progress;
+-------------+-------------+--------+
| progress_id | resource_id | rate |
+-------------+-------------+--------+
| 5 | 1 | 100.00 |
+-------------+-------------+--------+
1 row in set (0.00 sec)