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
PRIMARY KEY (
index user_login(username,password),#用户登陆时查询
index(email),#邮箱有效性查询
index(activecode)#注册激活码查询
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;
评论表设计:(提示:id 字段 时重点 其他的字段不是本设计关心的重点)
CREATE TABLE
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点赞再次点击后取消:
//与主体无关:
附: 该栏目 整体预览:
前言:微博热门动态点赞表设计
前天和师兄(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(
idint unsigned NOT NULL AUTO_INCREMENT,
usernamevarchar(30) DEFAULT NULL,
passwordvarchar(30) DEFAULT NULL,
nicknamevarchar(20) DEFAULT NULL,
message_countint unsigned DEFAULT 0, #用户收到的消息
tiezi_countint unsigned DEFAULT 0, #用户发的帖子
huifu_countint unsigned DEFAULT 0, #用户回复的帖子
phonebigint unsigned DEFAULT 0, #手机号码
icon_urlvarchar(100) DEFAULT NULL, #用户头像的URL
rolechar(5) DEFAULT NULL , #用户角色 黄铜 白银 黄金 白金 钻石 大师 版主 管理员
statetinyint unsigned DEFAULT 0, #用户状态 游客-1 未激活0 在线1 离线2 锁定3
activecodevarchar(50) DEFAULT NULL, #激活码
member_pointtinyint unsigned,
sexchar(1) DEFAULT ‘男’,
weixingvarchar(50), #微信号
addressvarchar(50), #地址
schoolvarchar(50), #学校
majorvarchar(50), #专业
introducevarchar(100),
agetinyint unsigned,
hometownvarchar(50),
birthdayvarchar(50),
last_login_ipvarchar(50), #上次登陆时IP地址
register_ipvarchar(50), #注册时IP地址
last_login_timetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, #上次登陆时间
login_timetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, #本次登陆时间
createtimetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , #改记录创建时间
updatetimetimestamp 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(
idint(11) NOT NULL PRIMARY KEY auto_increment,
group_idint(11) NOT NULL ,
create_useridint(11) NOT NULL ,
create_usernamevarchar(50) DEFAULT NULL ,
create_timevarchar(50) DEFAULT NULL ,
create_username_iconvarchar(100) DEFAULT NULL,
textvarchar(255) DEFAULT NULL,
click_countint(11) DEFAULT 0 ,
author_commentvarchar(255) DEFAULT NULL,
gmt_createdatetime DEFAULT CURRENT_TIMESTAMP,
gmt_modifieddatetime DEFAULT CURRENT_TIMESTAMP,
is_pendingtinyint(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点赞再次点击后取消:
//与主体无关:
附: 该栏目 整体预览:
相关文章推荐
- JavaEE框架Bootstrap HTML5 jQuery SpringMVC maven mybatis shiro ehcache java web
- Java源码 SpringMVC Mybatis Shiro Bootstrap Rest Webservice
- springMVC+MyBatis+Oracle+Web实现增删改查(附带完整案例+数据库数据)
- 手把手教你搭建自己的Java Web(Android)项目(SpringMVC + Mybatis服务端,Html5 Web端, Android客户端实现)
- web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
- ASP.NET MVC和WebForm 轻松实现前端和后端的双重验证 jquery.validate+ValidationSugar
- SSM框架+WebSocket实现网页聊天(Spring+SpringMVC+MyBatis+WebSocket)
- web的各种前端打印方法之jquery打印插件jqprint实现网页打印(转载)
- JavaEE框架Bootstrap HTML5 jQuery SpringMVC maven mybatis shiro
- SpringSecurity+SpringMVC +Mybatis3.0实现的web小框架
- web的各种前端打印方法之jquery打印插件PrintArea实现网页打印(转载)
- jetty+bootstrap Carousel+springMVC+mybatis实现表格数据的轮播
- Maven + Spring MVC+Mybatis + MySQL +AngularJS + Bootstrap 实现简单微博应用(三)前后台交互
- SpringMVC+Mybatis+Oracle实现web分页
- NHibernate+spring.net+jquery打造UI控件库(mvc+webform两种实现) 不是extjs
- web的各种前端打印方法之jquery打印插件jqprint实现网页打印
- 练习搭建spring+springmvc+mybatis实现java web登陆
- 菜鸟使用SSM框架搭建web服务器实现登录功能(Spring+SpringMVC+Mybatis)
- web的各种前端打印方法之jquery打印插件jqprint实现网页打印