您的位置:首页 > Web前端 > BootStrap

WEB网页实现微信公众号点赞实现--前端:jquery+bootstrap||后端springmvc+mybatis

2017-08-19 23:11 706 查看
个人交友网站点赞数据库设计

前言:微博热门动态点赞表设计

前天和师兄(antfin)讨论的对话:

小白我:类似于微博,可以为主题点赞,但不能重复点赞。目前的设计是有一个字段(varchar(max)),记录所有点过的用户id,类似于:311000|3110001|………..|3110002这样每次用户点赞就要根据这个字段判断是否已经赞过。感觉这样设计不是很好,请问这样的表怎么设计比较好?谢谢师兄指导。

师兄:如果按照传统数据库设计的理念,微博和用户是多对多关系,应该单立出一个关系表,包含微博表和用户表的主键,另外还可以包含“点赞”这个关系特有的属性,比如状态(避免反复取消和重点造成频繁删除和插入)、时间之类的。但是,如果真的像微博那么大量的话,这种方式恐怕无法满足性能的要求。其实,我觉得你用的方法是可以的,只不过不能每次点赞和取消都用数据库的方式来操作。应该把“赞”这个字段的数据加载到内存中,点赞和取消都在内存中完成,然后定期把内存中的数据按照你的格式写入数据库。当然,这会造成内存和数据库中的数据不一致,如果真出现宕机,可能会丢失一部分“赞”,但我觉得“赞”这个数据其实并不关键,多一点少一点不是什么致命的问题。可以根据点赞和取消的次数来设定写库的频率,以避免内存和数据库中的数据差异过大。另外,可能还需要一个类似LRU的算法管理内存中缓存的“赞”数据。

师兄:前天问了公司的DBA,向他请教了这个问题。把点赞用户的ID都塞到一个LOB字段中,最大的问题还是不便于检索和更新。比如,一个用户打开一条微博,会显示出他有没有点过赞,这就要扫描LOB字段的内容,而字段内容是无序的,远没有索引高效;点赞之后,如果取消或者重点,需要把整个字段读出来进行修改,这无形中读写了很多不相关的内容。当然,你可以在用户表中增加一个类似字段,包含用户点过赞的所有微博的ID,这个字段的长度会相对小得多,但对于长期使用的用户,依然存在上述问题。我也跟他提了把数据加载到内存中操作的想法。他认为,这样的方式内存开销过大,即每条被访问的微博的“赞”数据都需要完整地读到内存中。就算通过一些机制管理占用的内存,如果业务量很大的话,会造成缓存的“赞”数据频繁换入换出,即turnover,性能根本无法保障。所以,是我有点想当然了。其实,问题的症结还是在于这样存储数据的方式不便于只对“部分”进行操作。按照他的说法,1.新浪采用的还是传统的关系表的方式。我也提了这样集中存储,是否会因为表数据过大而造成低效。他说新浪采用的是对2.数据库做shading,有效地将数据分散在多个节点上。因为时间仓促,也没来得及详细问他们的数据库设计和架构方案。

师兄: 如果你的用户数,并不多的话, 可以采用“记录所有点过的用户id,类似于:311000|3110001|3110002 ” 这个方式 ,用着很方便,但是用户量一上来,就慢的要命。建议使用,单独的点赞表机制,每天的微博有单独的分区,点赞表也按这个分区,每次查询时,就可以知道从哪个分区表去查,速度能快不少。 师兄:这是经典的数据库设计中处理多对多关系的方式。这样的记录数会特别多,每一个用户赞过的每一条微博都会有一条记录,如果真的像新博微博业务量那么大的话,就要考虑做分库分表(即sharding)了。这种方案就复杂多了,我也没做过。你再根据你的业务情况考虑一下吧。

设计点赞数据库

用户表设计:(提示:id 字段 时重点 其他的字段不是本设计关心的重点)

CREATE TABLE
qunalang_user
(

id
int unsigned NOT NULL AUTO_INCREMENT,

username
varchar(30) DEFAULT NULL,

password
varchar(30) DEFAULT NULL,

nickname
varchar(20) DEFAULT NULL,

email
varchar(30) DEFAULT NULL,

message_count
int unsigned DEFAULT 0, #用户收到的消息

tiezi_count
int unsigned DEFAULT 0, #用户发的帖子

huifu_count
int unsigned DEFAULT 0, #用户回复的帖子

phone
bigint unsigned DEFAULT 0, #手机号码

icon_url
varchar(100) DEFAULT NULL, #用户头像的URL

role
char(5) DEFAULT NULL , #用户角色 黄铜 白银 黄金 白金 钻石 大师 版主 管理员

state
tinyint unsigned DEFAULT 0, #用户状态 游客-1 未激活0 在线1 离线2 锁定3

activecode
varchar(50) DEFAULT NULL, #激活码

member_point
tinyint unsigned,

sex
char(1) DEFAULT ‘男’,

weixing
varchar(50), #微信号

address
varchar(50), #地址

school
varchar(50), #学校

major
varchar(50), #专业

introduce
varchar(100),

age
tinyint unsigned,

hometown
varchar(50),

birthday
varchar(50),

last_login_ip
varchar(50), #上次登陆时IP地址

register_ip
varchar(50), #注册时IP地址

last_login_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, #上次登陆时间

login_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, #本次登陆时间

createtime
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , #改记录创建时间

updatetime
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, #记录修改时间

PRIMARY KEY (
id
),

index user_login(username,password),#用户登陆时查询

index(email),#邮箱有效性查询

index(activecode)#注册激活码查询

) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;

评论表设计:(提示:id 字段 时重点 其他的字段不是本设计关心的重点)

CREATE TABLE
qunalang_tuodan_comment
(

id
int(11) NOT NULL PRIMARY KEY auto_increment,

group_id
int(11) NOT NULL ,

create_userid
int(11) NOT NULL ,

create_username
varchar(50) DEFAULT NULL ,

create_time
varchar(50) DEFAULT NULL ,

create_username_icon
varchar(100) DEFAULT NULL,

text
varchar(255) DEFAULT NULL,

click_count
int(11) DEFAULT 0 ,

author_comment
varchar(255) DEFAULT NULL,

gmt_create
datetime DEFAULT CURRENT_TIMESTAMP,

gmt_modified
datetime DEFAULT CURRENT_TIMESTAMP,

is_pending
tinyint(3) unsigned DEFAULT NULL,

index(group_id,create_userid)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

//======================
4000
=================================

重点分析:用户 评论 多对多关系中间表

CREATE TABLE qunalang_comment_user(

id int NOT NULL PRIMARY KEY auto_increment,

comment_id int NOT NULL COMMENT ‘评论的id’,

user_id int NOT NULL COMMENT ‘用户的id’,

deleteFlag tinyint unsigned NOT NULL DEFAULT 1 COMMENT ‘点赞标识:1点赞;0取消’,

index (comment_id, user_id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

关注点 1. 该表包含 用户表和评论表的主键id

2. 是否删除标志位:防止用户重复点赞和取消导致对数据库的频繁插入。用户对一条评论点赞后,往中间表插入点赞记录,点赞后又取消点赞,修改是由删除标志位。

3. 索引的建立:评论id 用户id的联合索引。

//===========================代码实现===============================================

1.控制器:

@RequestMapping(“/add”)

@ResponseBody

public Boolean addcomment_user(@RequestParam(“tuodan_comment_id”)Integer tuodan_comment_id,HttpServletRequest request){

// 1.从session中获取用户的id

Integer user_id = (Integer) request.getSession().getAttribute(Constant.ID);

//2.comment_user

Comment_user comment_user=new Comment_user();

comment_user.setComment_id(tuodan_comment_id);

comment_user.setUser_id(user_id);

//3.数据库

boolean hasComment=comment_UserService.isClickByComment_idAndUser_id(tuodan_comment_id, user_id);

if(hasComment==false){

comment_UserService.addClickByComment_idAndUser_id(tuodan_comment_id, user_id);

//点赞成功

return true;

}else{

//取消点赞

comment_UserService.removeClickByComment_idAndUser_id(tuodan_comment_id, user_id);

return false;

}

}

2.前端 实现

查出数据用 jquery 循环json 数据



效果:

1点赞:



2点赞再次点击后取消:



//与主体无关:

附: 该栏目 整体预览:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐