hello大家好,我是卷卷毛,我又回来了
这次给大家带来一个支持回复功能的留言板的设计方案,这个留言板现在就正运行在我的个人博客中,它支持简单的留言、回复功能,先来看一下效果图:
欢迎大家来留言板逛逛呀,有意见建议可以留言~【留言板】
还挺简洁大方的对吧,不过这次我们讨论的重点不在前端的页面,而是后端的逻辑。
所以还是先说回留言板的开发。
首先,关于使用的技术:
- 后端整体框架是Spring Boot
- 数据库使用的是MySQL
- ORM框架使用的是Mybatis
设计这个功能的过程,我的顺序是数据库->后端->前端
所以在着手开发后台功能之前,首先要对数据库表进行设计。
如果留言板仅支持留言而不支持回复的话,那设计整体就会简单不少,先记录内容,昵称,留言时间等几个简单信息字段。
而由于加上了回复功能,这就会产生一些难题。
对回复功能的探讨
设计回复功能,一个绕不过去的问题就是回复消息和被回复消息的关联方式。
简单一些,我们可以在每条留言中加上一个字段记录被回复的留言id,像这样:
对于一条回复,该字段是被回复留言的id,对于一条留言,该字段就为0。这样就可以区分留言和回复啦。
于是按照这个设计思路,查询时可以根据这个字段联结表自身,获取到一条留言及其回复。
而如果我们更进一步,需求对回复也能够回复,那么这样的设计就存在问题。
如果需要两层回复,那么就是联结两次自身,三层就是四次。。。。。
可是谁知道用的时候,留言者会回复多少层呢?万一在留言板对开线了,多少层可都不够用的。。。
那么上面的设计有一个问题就是只能满足有限层的回复,究其原因,是因为其数据结构是一棵树,而且没有深度限制,任何一个节点下面都可以扩展新的节点。
我们来简单模拟一段留言:
这样的树形结构,不好查还只是一方面的原因,另一方面,即使将整个树结构查询出来,在评论区也不便于展示。
为了解决这个问题,我们观察各方留言板,评论区的设计方案。会发现他们也在避免出现对树形结构进行嵌套的问题。
一种可行的解决方案,也是博主使用的方案,是在查询时仅保留节点和根节点之间的祖孙关系,节点之间则按照发布时间先后排序成线性结构,并记录父节点。
简单点说,就是每个回复除了记录被回复的记录,还要记录下最初的留言id,在查询时,先根据回复记录id
获取到被回复记录的信息(主要是昵称),再根据最初留言id进行查询分组,小组内按照时间先后排序。
形象一点,就是:
查出来是这样:
其实就是除了根,其他部分的树都给拍扁了,但是之间的链接关系还在。
数据库表及model设计
于是,加上回复的根留言id以及一个控制字段,最终的表设计如下:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for note
-- ----------------------------
DROP TABLE IF EXISTS `note`;
CREATE TABLE `note` (
`n_id` int(0) NOT NULL AUTO_INCREMENT COMMENT '留言id',
`content` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '留言内容',
`nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '留言昵称',
`time` datetime(0) NULL DEFAULT NULL COMMENT '留言时间',
`res_id` int(0) NULL DEFAULT NULL COMMENT '回复对象id',
`reply_post` int(0) NULL DEFAULT NULL COMMENT '留言所属条目',
`is_delete` int(0) NULL DEFAULT 0 COMMENT '是否删除(1删除 0不删除)',
PRIMARY KEY (`n_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 52 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
完成了对表的设计,接着就是后台中的对象类:
里面出现了一些新的变量,
respondent
回复对象的昵称follows
回复列表,这个就是拍扁了的树体部分。只有根留言有