mysql插入唯一
本文于 1921 天之前发表,文中内容可能已经过时。
在需要保证数据唯一性的场景中,个人觉得任何使用程序逻辑的重复校验都是不可靠的,这时只能在数据存储层做唯一性校验。MySQL 中以唯一键保证数据的唯一性,那么若新插入重复数据时,我们可以让 MySQL 怎么来处理呢?
一个简单的处理逻辑,用户存在的时候更新数据,用户不存在的时候插入数据1
2
3
4
5
6
7
8// 这段代码通过程序逻辑去试图保证唯一性,但是在高并发情况下,并不能保证数据唯一性,因为不是原子性操作
if($user){
UserInfo::where('open_id', $openId)->update([
'last_visit_time' => time()
]);
}else{
UserInfo::create($update);
}
在用户访问量多起来的时候,就会有重复的数据插入了。为了避免这种问题的出现,最先想到的是添加唯一索引。这样可以解决这个问题,但是还是会有重复插入的操作。在进行请求的时候,会直接抛出异常。有时候直接抛出异常会造成程序崩溃。
解决这种问题可以有很多方法,可以使用锁机值,确保插入的时候没有重复数据。或者使用下面的解决。
Replace Into 方式的行为为当存在 Unique 相同的记录,则 覆盖 原有记录。实则为 Delete 和 Insert 两组合的原子操作,会改变该条记录的主键。
1
REPLACE INTO `allowed_user` (`uid`, `last_time`) VALUES ('8e9b8c14-fae8-49d4-bbac-a733c09ec82f', '2017-09-01 19:31:15')
On Duplicate Key Update 该方式当存在 Unique 相同的记录时,执行 Update 子句更新记录,否则执行 Insert 子句插入新记录。在 Update 时记录的主键并不会改变。
1
INSERT INTO `allowed_user` (`uid`, `last_time`) VALUES ('8e9b8c14-fae8-49d4-bbac-a733c09ec82f', '2017-09-01 19:31:15') ON DUPLICATE KEY UPDATE `last_time` = '2017-09-01 19:40:15'
Ignore 方式为在 Unique 相同的记录时,不做任何更新和插入操作,忽略本条记录,一般不使用。
1
INSERT IGNORE INTO `allowed_user` (`uid`, `last_time`) VALUES ('8e9b8c14-fae8-49d4-bbac-a733c09ec82f', '2017-09-01 19:41:15')