当一天的工作量比较大的时候,我们有时候都会被自己写的语句给蒙到。以下是本人工作中遇到的情况
1、on duplicate key update 写多了set :
insert into t_abcd(a,b,c,d) values(1,1,1,1) on duplicate key update set a =2
而正确的写法应该是: insert into t_abcd(a,b,c,d) values(1,1,1,1) on duplicate key update a =2
2、对于有自增ID的主键,又有时间的,常常使用order by `time` desc 而不是使用order by id desc;
在此情况下为了提高查询效率,应该使用 order by id desc;
3、对于每天奖励领取的,在用户领取的时候,特别要留意更新的语句;
如:
新年活动,玩家充值后,即可每天领取300个金币。判断是否领取的条件是使用getTime的字段。
1)、先查询领取时间:getTime if(getTime<now()) 则可领取:
2)、更新int isGet = "update table_A set getTime=now() where userID=? "
3)、isGet>0 再执行 充值金币逻辑语句。
其实以上的逻辑是有问题的。特别是在几台服务器做负载均衡的时候;用户随便写一个批量请求的脚本就可以领取多次金币了;因为每次请求,当获取到的time<now()后,执行更新,而且是可以更新的,因为res在此环节下的结果返回的都是>1。
解决方法:使用数据库的更新条件加以判断即可:
update table_A set getTime=now() where userID=? and getTime < convert(now(),date);
4、对于键表,如果是记录次数的,最好先default 0;如果不default 0,那么在初始化的时候一定要赋值。否则,在执行语句update set num = num + 1 的时候,是不会报错的:
create table tb_test(
id int(11) auto_increment,
a tinyint(3),
primary key (id)
)engine=innodb default character set=utf8mb4;
insert into tb_test(id) values(1);
update tb_test set a=a+1 where id = 1;
select *from tb_test;
正确的建表:
create table tb_test(
id int(11) auto_increment,
a tinyint(3) default 0,
primary key (id)
)engine=innodb default character set=utf8mb4;
2015-03-02更新:
mysql