博罗做网站技术,做网站的大型公司,建设银行网站一直打不开,云版erp系统功能介绍场景#xff1a;统计每个活动的用户访问量#xff0c;且每个用户仅统计一次。
首先活动表是已经存在了的#xff0c;一般情况下#xff0c;我们都会在创建一个用户访问表#xff0c;其中唯一主键是用户ID活动ID作为唯一主键
create table user_visist_activity_record(i…场景统计每个活动的用户访问量且每个用户仅统计一次。
首先活动表是已经存在了的一般情况下我们都会在创建一个用户访问表其中唯一主键是用户ID活动ID作为唯一主键
create table user_visist_activity_record(id int(11) NOT NULL AUTO_INCREMENT,user_id int(11) NOT NULL COMMENT 用户ID,activity_id int(11) NOT NULL COMMENT 活动ID,create_id bigint(20) NULL DEFAULT NULL COMMENT 创建人,update_id bigint(20) NULL DEFAULT NULL COMMENT 修改人,create_time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,update_time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 修改时间,deleted_ind tinyint(1) NOT NULL DEFAULT 0 COMMENT 是否删除0未删除1删除,PRIMARY KEY (id) USING BTREE,
unique index user_activity(user_id,activity_id)
) ENGINE InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 活动访问记录表 ROW_FORMAT Dynamic;创建了用户活动的访问记录表用户访问当期活动时都会查询一次表格内容来判断用户是否访问过该用户如果已存在了则不走后续逻辑。
在深入思考一下是否有更高效的方式呢毕竟每次都需要查询数据库一次而且这种活动访问的用户也不少。业务也需要统计多少用户访问了当前页面功能是无法砍掉。为了保证这个活动不影响主数据库可能会将当前功能拆分出去且数据库也非主数据库。那如果没有拆分服务的情况下又该如何解决呢
Redis BitMap
此时是否有想到通过redis的方式来解决毕竟查询redis比查询mysql快多了。
简单介绍一下BitMap BitMap就是位图其实也就是字节数组byte array用二进制表示只有 0 和 1 两个数字位图就是用每一个二进制位来存放或者标记某个元素对应的值。通常是用来判断某个数据存不存在的因为是用bit为单位来存储所以Bitmap本身会极大的节省储存空间。 如下图字符串在计算机里是由二进制的形式保存的。
在redis中有一个bitMap的数据结构因为每一个bit都是一条记录只需要把key值设置成活动ID而bit为设置用户访问的次数1代表访问过0则表示没有访问过。那么就不需要创建表格来统计当前用户是否访问过。甚至也不需要对活动表的用户访问数进行更新。这样的操作至少省略了两次数据库的操作。一次是判断用户对当前记录是否访问过一次是对活动表的用户访问数进行更新。
业务逻辑
string key pre activityId;
if(redis.has(key)) {// 第一次访问时没有key的记录// 判断当前活动是否存在活动是否过期等业务操作//redis.setBit(key, userId, 1);redis.expire(key, expireTime);
} else {if(redis.getBit(key, userId)) {return}redis.setBit(key, userId, 1);
}redis bitmap三个操作
添加 SETBIT命令
SETBIT key offset value (offset为偏移量value设置的值在上述中将offset设置为用户IDvalue直接设置为1)
查询GETBIT命令
GEIBIT KEY OFFSET (offset为偏移量offset为用户ID
统计BITCOUNT命令
BITCOUNT key 统计整个key上为1的个数