开始我用的是最方便的方法:使用 MySQL 的 count 一下活动记录表某个活动的数量,再+1就等于这个活动活动记录的编号。但是这个方案在并发的时候很容易出现编号重复的 BUG,显然这不是我们想要的。
因为要执行两条分开的 MySQL 语句(下面的语句只是提供大概思路,具体代码要根据你的项目使用的框架写法不一样):
12
$count=mysql_query("SELECT COUNT(*) FROM activity_records WHERE `activity_id` = activityId");mysql_query("INSERT INTO activity_records (number, user_id, activity_id) VALUES ($count+1, userId, activityId)");
因为 MySQL 是单进程多线程架构的数据库。
后来有朋友介绍用 MySQL 的联合唯一索引的方法把 number 字段和 activityId 字段联合一下。执行语句就可以了:
-- ------------------------------ Function structure for `currval`-- ----------------------------DROPFUNCTIONIFEXISTS`currval`;DELIMITER;;CREATEDEFINER=`root`@`%`FUNCTION`currval`(`value`int(11),`userId`int(11),`activityId`int(11))RETURNSint(11)BEGININSERTINTOactivity_records(number,user_id,activity_id)VALUES(value+1,userId,activityId);RETURNvalue+1;END;;DELIMITER;-- ------------------------------ Function structure for `nextval`-- ----------------------------DROPFUNCTIONIFEXISTS`nextval`;DELIMITER;;CREATEDEFINER=`root`@`%`FUNCTION`nextval`(`userId`int(11),`activityId`int(11))RETURNSint(11)BEGINDECLAREvalueINTEGER;SETvalue=0;SELECTCOUNT(*)INTOvalueFROMactivity_recordsWHERE`activity_id`=activityId;RETURNcurrval(value,userId,activityId);END;;DELIMITER;