在项目中偶尔会有这种需求,用户通过第三方系统登录时如果尚未注册,则自动给用户注册,注册过的用户则自动登录,更新最近登录时间等信息。有时候图省事可能就直接INSERT INTO user ON DUPLICAET KEY UPDATE...一句 SQL 解决了,功能没问题,只是如果用户表中有auto_increment字段,则容易导致auto_increment字段产生空洞问题,一段时间后会发现用户ID会经常出现不连续的情况,虽然MySQL的自增ID一般都够用,但是如果能减少不必要的空洞更好。
场景
当用户从第三方登录时,假定用的是手机号做唯一标识,通常在我们自己的系统中会建一个用户表,如下(MySQL版本为5.5.58,隔离级别为Repeatable Read):
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`mobile` varchar(11) DEFAULT NULL,
`last_login_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
当用户从第三方登录时,我们校验通过后,会将手机号插入到user表里注册用户。如果用户已经存在,则更新最后登录时间,为了简便,经常像下面这么做,功能上看起来是没错的,问题就是运行一段时间后会发现