针对社区的特点,本应用分为五个模块:

  • 用户模块
  • 文章模块
  • 评论模块
  • 消息模块
  • 通用模块

下面针对具体的模块进行分析。

用户模块

整个用户模块从功能上可以分为:

  • 注册登录
  • 权限管理
  • 业务逻辑

注册登录

注册登录除了常见的用户名+密码登录的方式之外,还有手机号+验证码、邮箱+验证码、第三方授权登录等。这里我们采用的是微信公众号登录方式。主要的考量是用户会觉得更加安全与方便(既不需要使用手机号,也不用担心密码泄露)。因为是个人公众号,不能实现扫码自动登录,我们采取的策略是:

  • 用户点击登录,登录页显示二维码+验证码–>用户关注公众号,将登录页面上的验证码输入到微信公众号->自动登录。

库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`third_account_id` varchar(128) NOT NULL DEFAULT '' COMMENT '第三方用户ID',
`user_name` varchar(64) NOT NULL DEFAULT '' COMMENT '用户名',
`password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
`login_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登录方式: 0-微信登录,1-账号密码登录',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `key_third_account_id` (`third_account_id`),
KEY `key_user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户登录表';

上面的表结构设计,我们冗余了 user_name, password 用户名密码的登录方式,主要是给管理员登录后台使用。

用户首次登录之后,会在user表中插入一条数据,主要关注 third_account_id 这个字段,它记录的是微信开放平台返回的唯一用户id。

权限管理

我们将用户角色信息写入用户基本信息表中,没有单独抽出一个角色表,然后进行映射,主要是因为这个系统逻辑相对清晰,没有太复杂的角色关系,因此采用了轻量级的设计方案。库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE `user_info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
`photo` varchar(128) NOT NULL DEFAULT '' COMMENT '用户图像',
`position` varchar(50) NOT NULL DEFAULT '' COMMENT '职位',
`company` varchar(50) NOT NULL DEFAULT '' COMMENT '公司',
`profile` varchar(225) NOT NULL DEFAULT '' COMMENT '个人简介',
`user_role` int(4) NOT NULL DEFAULT '0' COMMENT '0 普通用户 1 超管',
`extend` varchar(1024) NOT NULL DEFAULT '' COMMENT '扩展字段',
`ip` json NOT NULL COMMENT '用户的ip信息',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `key_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户个人信息表';

业务逻辑

业务逻辑模块,我们从两个角度去思考问题:用户的轨迹和用户之间的订阅关注。

1. 订阅关注

订阅关注这块业务主要是用户可以相互关注,核心点就在于维护用户与用户之间的订阅关系,核心就是需要一张表来记录关注与被关注情况。

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `user_relation` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '作者用户ID',
`follow_user_id` int(10) unsigned NOT NULL COMMENT '关注userId的用户id,即粉丝userId',
`follow_state` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '关注状态: 0-未关注,1-已关注,2-取消关注',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_follow` (`user_id`,`follow_user_id`),
KEY `key_follow_user_id` (`follow_user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户关系表';

2.用户轨迹

我们希望记录用户的阅读历史、关注列表、收藏列表、评价的文章列表,对于这种用户行为轨迹的诉求,我们采用设计一张大宽表的策略,其主要目的在于:

  1. 记录用户的关键动作
  2. 便于文章的相关计数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE TABLE `user_foot` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`document_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文档ID(文章/评论)',
`document_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '文档类型:1-文章,2-评论',
`document_user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '发布该文档的用户ID',
`collection_stat` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '收藏状态: 0-未收藏,1-已收藏,2-取消收藏',
`read_stat` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '阅读状态: 0-未读,1-已读',
`comment_stat` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '评论状态: 0-未评论,1-已评论,2-删除评论',
`praise_stat` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '点赞状态: 0-未点赞,1-已点赞,2-取消点赞',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_user_doucument` (`user_id`,`document_id`,`document_type`),
KEY `idx_doucument_id` (`document_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户足迹表';

我们将用户 + 文章设计唯一键,用来记录用户对自己阅读过的文章的行为,因此可以直接通过这个表获取用户的历史轨迹,同时也可以从文章的角度出发,查看被哪些用户点赞、收藏过。

在项目中,我们对于文章提供了点赞收藏评论三种交互。

其中点赞与收藏,实际上就是用户与文章之间的操作行为,可以通过前面的user_foot表记录。 文章的统计计数就是根据这个表数据来的,当前用户与文章的点赞、收藏关系,同样是根据这个表来的。唯一需要注意的点,就是这个数据的插入、更新策略:

  • 首次阅读文章时:插入一条数据
  • 点赞:若记录存在,则更新状态,之前时点赞的,设置为取消点赞;若记录不存在,则插入一条点赞的记录
  • 收藏:同上

文章模块

我们将文章和专栏都放在一起,同样也将类目管理、标签管理等也都放在这个模块中。这里放在一起的主要原因在于他们都是围绕基本的文章这一业务属性来的,可以聚合在一起。文章模块主要分为以下几个部分:

  • 文章
  • 分类
  • 标签
  • 专栏

文章

文章的核心就在于发布、查看。基本的发布流程:

  1. 用户登录,进入发布页面
  2. 输入标题、文章
  3. 选择分类、标签,封面、简介
  4. 提交文章,进入待审核状态,仅用户可看详情
  5. 管理员审核通过,所有人可看详情

因为文章的内容通常较大,在很多的业务场景中,我们实际上是不需要文章内容的,如首页、推荐列表等都只需要文章的标题等信息;此外我们也希望对文章做一个版本管理(比如上线之后,再修改则新生成一个版本)

因此我们对文章设计了两张表

库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
-- article definition

CREATE TABLE `article` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`article_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '文章类型:1-博文,2-问答',
`title` varchar(120) NOT NULL DEFAULT '' COMMENT '文章标题',
`short_title` varchar(120) NOT NULL DEFAULT '' COMMENT '短标题',
`picture` varchar(128) NOT NULL DEFAULT '' COMMENT '文章头图',
`summary` varchar(300) NOT NULL DEFAULT '' COMMENT '文章摘要',
`category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '类目ID',
`source` tinyint(4) NOT NULL DEFAULT '1' COMMENT '来源:1-转载,2-原创,3-翻译',
`source_url` varchar(128) NOT NULL DEFAULT '1' COMMENT '原文链接',
`offical_stat` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '官方状态:0-非官方,1-官方',
`topping_stat` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '置顶状态:0-不置顶,1-置顶',
`cream_stat` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '加精状态:0-不加精,1-加精',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-未发布,1-已发布',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `idx_category_id` (`category_id`),
KEY `idx_title` (`title`),
KEY `idx_short_title` (`short_title`)
) ENGINE=InnoDB AUTO_INCREMENT=173 DEFAULT CHARSET=utf8mb4 COMMENT='文章表';


-- article_detail definition

CREATE TABLE `article_detail` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`article_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章ID',
`version` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '版本号',
`content` longtext COMMENT '文章内容',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_article_version` (`article_id`,`version`)
) ENGINE=InnoDB AUTO_INCREMENT=141 DEFAULT CHARSET=utf8mb4 COMMENT='文章详情表';

分类

文章对应的分类,我们要求一个文章只能挂在一个分类下

1
2
3
4
5
6
7
8
9
10
11
12
-- category definition

CREATE TABLE `category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`category_name` varchar(64) NOT NULL DEFAULT '' COMMENT '类目名称',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-未发布,1-已发布',
`rank` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='类目管理表';

标签

文章对应的标签属性,一个文章可以有多个标签,需要增加一个n*m的关系表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-- tag definition

CREATE TABLE `tag` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tag_name` varchar(120) NOT NULL COMMENT '标签名称',
`tag_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '标签类型:1-系统标签,2-自定义标签',
`category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '类目ID',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-未发布,1-已发布',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `idx_category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=147 DEFAULT CHARSET=utf8mb4 COMMENT='标签管理表';

-- article_tag definition

CREATE TABLE `article_tag` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`article_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章ID',
`tag_id` int(11) NOT NULL DEFAULT '0' COMMENT '标签ID',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `idx_tag_id` (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=145 DEFAULT CHARSET=utf8mb4 COMMENT='文章标签映射';

专栏

专栏主要是一系列文章的合集,基于此最简单的设计方案就是加一个专栏表,然后再加一个专栏与文章的映射表。但是需要注意的是专栏中文章的顺序支持调整

专栏表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- column_info definition

CREATE TABLE `column_info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '专栏ID',
`column_name` varchar(64) NOT NULL DEFAULT '' COMMENT '专栏名',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '作者id',
`introduction` varchar(256) NOT NULL DEFAULT '' COMMENT '专栏简述',
`cover` varchar(128) NOT NULL DEFAULT '' COMMENT '专栏封面',
`state` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 0-审核中,1-连载,2-完结',
`publish_time` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '上线时间',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`section` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
`nums` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '专栏预计的更新的文章数',
`type` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '专栏类型 0-免费 1-登录阅读 2-限时免费',
`free_start_time` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '限时免费开始时间',
`free_end_time` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '限时免费结束时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='专栏';

专栏文章表

1
2
3
4
5
6
7
8
9
10
11
12
-- column_article definition

CREATE TABLE `column_article` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`column_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '专栏ID',
`article_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章ID',
`section` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '章节顺序,越小越靠前',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `idx_column_id` (`column_id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 COMMENT='专栏文章列表';

评论模块

评论可以是针对文章进行,也可以是针对另外一个评论进行回复,我们的做法是将回复也当作是一个评论统一处理。

img

我们将评论和回复都当成普通的评论,只是主体不同而已,因此一篇文章的评论列表,我们需要重点关注的就是,如何构建评论与其回复之间的层级关系。

对于这种评论与回复的层级关系,可以是建辅助表来处理;也可以是表内的父子关系来处理,这里我们采用第二种策略

  • 每个评论记录它的上一级评论id(若只是针对文章的评论,那么上一级评论id = 0)
  • 我们通过父子关系,在业务层进行逻辑还原。

库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- comment definition

CREATE TABLE `comment` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`article_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章ID',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`content` varchar(300) NOT NULL DEFAULT '' COMMENT '评论内容',
`top_comment_id` int(11) NOT NULL DEFAULT '0' COMMENT '顶级评论ID',
`parent_comment_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父评论ID',
`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `idx_article_id` (`article_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8mb4 COMMENT='评论表';

注意,在这个表中,我们冗余了一个顶级评论id(top_comment_id),主要目的是为了简化业务层评论关系还原的复杂性。

通过上面的表结构,关系还原的策略:

  • 先查出文章的顶级评论(parent_comment_id = 0)
  • 接下来就是针对每个顶级评论,查询它下面的所有回复 ( top_comment_id = comment_id)
    • 构建顶级评论下的回复父子关系(根据parent_comment_id来构建依赖关系)

关于评论点赞☆

我们同样支持对评论进行点赞,取消点赞;对于点赞的整体业务逻辑操作,实际上与文章的点赞一致,因此我们直接复用了文章的点赞逻辑,借助 user_foot 来实现的。

消息模块

消息模块主要是记录一些定义的事件,用于同步给用户;我们首先采用Spring Event/Listener的异步方案来进行;然后引入消息队列MQ进行解耦。

我们主要定义以下五种消息类型

  • 评论
  • 点赞
  • 收藏
  • 关注
  • 系统消息

img

当发生方面的行为之后,在相应的地方进行主动埋点,手动发送一个消息事件,然后异步消费事件,生成消息通知。

  • 当用户点赞了一个文章,产生一个点赞消息之后;又取消了点赞,这个消息会怎样?
  • 撤销还是依然保留?(我们选择的方案是撤销

库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- notify_msg definition

CREATE TABLE `notify_msg` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`related_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '关联的主键',
`notify_user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '通知的用户id',
`operate_user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '触发这个通知的用户id',
`msg` varchar(1024) NOT NULL DEFAULT '' COMMENT '消息内容',
`type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '类型: 0-默认,1-评论,2-回复 3-点赞 4-收藏 5-关注 6-系统',
`state` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '阅读状态: 0-未读,1-已读',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
KEY `key_notify_user_id_type_state` (`notify_user_id`,`type`,`state`)
) ENGINE=InnoDB AUTO_INCREMENT=1086 DEFAULT CHARSET=utf8mb4 COMMENT='消息通知列表';

通用模块

通用模块包括以下几种:

  • 统计计数
  • pv/uv
  • 全局字典
  • 图片上传
  • 搜索推荐

统计计数

针对文章的阅读计数,没访问一次计数+1, 因此前面的user_foot不能使用(因为未登录的用户是不会生成user_foot记录的),库表设计如下:

1
2
3
4
5
6
7
8
9
10
11
12
-- read_count definition

CREATE TABLE `read_count` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`document_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文档ID(文章/评论)',
`document_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '文档类型:1-文章,2-评论',
`cnt` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '访问计数',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_document_id_type` (`document_id`,`document_type`)
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8mb4 COMMENT='计数表';

注意,上面这个计数表中的cnt的更新,使用 cnt = cnt + 1 而不是 cnt = xxx的方案

pv/uv

每天的请求pv/uv计数统计。

1
2
3
4
5
6
7
8
9
10
11
12
-- request_count definition

CREATE TABLE `request_count` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`host` varchar(32) NOT NULL DEFAULT '' COMMENT '机器IP',
`cnt` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '访问计数',
`date` date NOT NULL COMMENT '当前日期',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_unique_id_date` (`date`,`host`)
) ENGINE=InnoDB AUTO_INCREMENT=8708 DEFAULT CHARSET=utf8mb4 COMMENT='请求计数表';

全局字典

全局字典表主要是为了减少代码中的硬编码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- dict_common definition

CREATE TABLE `dict_common` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`type_code` varchar(100) NOT NULL DEFAULT '' COMMENT '字典类型,sex, status 等',
`dict_code` varchar(100) NOT NULL DEFAULT '' COMMENT '字典类型的值编码',
`dict_desc` varchar(200) NOT NULL DEFAULT '' COMMENT '字典类型的值描述',
`sort_no` int(8) unsigned NOT NULL DEFAULT '0' COMMENT '排序编号',
`remark` varchar(500) DEFAULT '' COMMENT '备注',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_type_code_dict_code` (`type_code`,`dict_code`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COMMENT='通用数据字典';

图片上传

文章的图片使用图床上传。

搜索推荐

后续考虑加入推荐功能

全部表汇总

image-20240326210024310