在Web开发中经常会遇到需要计数器表的场景,如果将计数器保存在表中,在操作表时可能会遇到并发问题。因此,通常的做法是为计数器单独建立一个表,在写入操作时通过事务在处理业务表的同时处理计数器。
比如一个典型的场景:记录新闻的浏览量。这个场景的表结构可能如下所示:
create table article(
article_id int unsigned auto_increment primary key,
article_author varchar(20) not null,
article_title varchar(50) not null,
article_content text not null
);
create table article_counter(
article_id int unsigned primary key,
cnt int unsigned not null
);
在添加或者删除新闻纪录时,需要在事务中操作计数器表。此时有一个问题,当大量的事务访问同一个新闻的计数器时,只能串行执行。
为了更高的并发更新性能,我们为计数器表增加一个池子slot,此时计数器表的结构如下:
create table article_counter(
article_id int unsigned,
slot tinyint unsigned,
cnt int unsigned not null,
<span style="white-space:pre"> </span>primary key(article_id,slot)
);
池子slot的存在使得每条新闻不再只有一个计数器,而是多个计数器。比如可以设置slot的大小是10。这样不同的事务在访问的时候,随机生成一个数字(1-10)作为slot,如何该slot存在则更