简介
之前想规划一个类似语雀的小型博客,用户分享资料、视频、文章等等,也想结合之前36镇收藏网址的设计模式。可惜后面因为某些缘故,没有继续完成这个思路的后续开发,写这篇文章主要是对一些用到的相关知识点做一下总结。
博客要素
一般一个博客都包含以下一些要素
- 首页:设有主题分类、热门文章、最新文章等模块,方便用户选择和浏览感兴趣的主题或文章。
- 文章内容:每篇文章包括标题、作者、发布时间、摘要和正文内容。通过清晰的排版和易读的文字呈现,确保读者能快速获取到想要的知识。
- 搜索功能:提供全文搜索功能,读者可以根据关键词搜索相关主题,让用户能快速找到感兴趣的文章。
- 评论和互动:为每篇文章设置评论区,读者可以对文章进行评论、提出问题或分享自己的见解。同时,可以设置点赞、分享等功能,增加读者与作者和其他读者的互动。
- 标签和分类:为每篇文章添加标签和分类,便于读者根据自己的兴趣和需求查找相关主题。
- 用户注册与登录:提供用户注册和登录功能,读者可以通过个人账户保存喜欢的文章、关注感兴趣的作者、收藏有用的资源等。
- 推荐和相关文章:根据读者的浏览历史和兴趣,系统可以提供相关文章推荐,使读者更容易发现和探索相关的知识。
- 多媒体支持:除了文字,还可以支持图片、视频等多媒体形式呈现知识内容,丰富读者的阅读体验。
- 管理后台:为管理员提供一个管理后台,可以管理文章的发布、编辑与删除,管理用户账户和评论,统计和分析网站流量等。
- 移动适应性:考虑到越来越多的用户在移动设备上访问博客,确保网站具备良好的移动适应性,可以在手机和平板上流畅阅读。
上面的要素基本是共性,展示的效果少不了UI的界面设计、互动少不了评论的元素在里面,还有就是想让更多的人访问到你的网站,除了搜索引擎SEO方面、当然还得有价值的东西的展示,就像我们买课程,也是要买对自己有价值相关的课程一样。
而我之前的设想就是将博客转换一下,如图:
一个知识库,作为一个博客系统般,这样可以存储多个不同的类库话题,切换不同的体系,当然这是个比较简单的设想,可以作为练习项目的开始 下面,打算从两方面做一下总结,数据库、NestJs应用
数据库设计
知识库博客的数据库设计关系图:
lua
+--------------+
| 用户表 |
+--------------+
|
|
|
|
+--------------+
| 知识库表 |
+-------------+ +--------------+
| 标签表 | |
+-------------+ +--------------+
| | 内容表 |
| +--------------+
|
|
+-------------+
| 分类表 |
+-------------+
| |
| V
+-------------+ +--------------+
| 评论表 | | 收藏表 |
+-------------+ +--------------+
在上述的关系图中,用户表存储用户的基本信息,内容表存储文章的信息,包括关联的用户、标签和分类等信息。标签表和分类表分别存储文章的标签和分类信息。评论表存储用户对文章的评论信息,收藏表存储用户收藏的文章信息。 这里主要写:
这几个数据表:
知识库
sql
CREATE TABLE `knowledge` (
`kid` tinyint(2) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`cname` varchar(15) NOT NULL DEFAULT '' COMMENT '知识库名称',
`keywords` varchar(255) DEFAULT '' COMMENT '关键词',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`path` varchar(100) NOT NULL DEFAULT '' COMMENT '图片封面',
`sort` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
上述SQL语句创建了一个名为knowledge
的表,包含以下字段:
kid
:主键id,使用tinyint
数据类型,范围是0到255,使用unsigned
表示非负数。cname
:知识库名称,使用varchar
数据类型,最大长度为15个字符,非空字段。keywords
:关键词,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。description
:描述,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。path
:图片封面,使用varchar
数据类型,最大长度为100个字符,非空字段。sort
:排序,使用tinyint
数据类型,范围是0到255,非空字段,默认为0。PRIMARY KEY (
kid)
:kid
字段作为主键。
数据库引擎选择了InnoDB,自增起始值为29,默认字符集为utf8。
分类表
sql
CREATE TABLE `category` (
`cid` tinyint(2) unsigned NOT NULL AUTO_INCREMENT COMMENT '分类主键id',
`cname` varchar(15) NOT NULL DEFAULT '' COMMENT '分类名称',
`keywords` varchar(255) DEFAULT '' COMMENT '关键词',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`path` varchar(100) NOT NULL DEFAULT '' COMMENT '图片封面',
`sort` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
`pid` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '父级栏目id',
`kid` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '属于哪个知识库的',
PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
上述SQL语句创建了一个名为category
的表,包含以下字段:
cid
:分类主键id,使用tinyint
数据类型,范围是0到255,使用unsigned
表示非负数。cname
:分类名称,使用varchar
数据类型,最大长度为15个字符,非空字段。keywords
:关键词,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。description
:描述,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。path
:图片封面,使用varchar
数据类型,最大长度为100个字符,非空字段。sort
:排序,使用tinyint
数据类型,范围是0到255,非空字段,默认为0。pid
:父级栏目id,使用tinyint
数据类型,范围是0到255,非空字段,默认为0。kid
:属于哪个知识库的分类,使用tinyint
数据类型,范围是0到255,非空字段,默认为0。PRIMARY KEY (
cid)
:cid
字段作为主键。
数据库引擎选择了InnoDB,自增起始值为29,默认字符集为utf8。
内容表
sql
CREATE TABLE `article` (
`aid` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '文章表主键',
`title` char(100) NOT NULL DEFAULT '' COMMENT '标题',
`content` mediumtext NOT NULL COMMENT '文章内容',
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '链接',
`keywords` varchar(255) NOT NULL DEFAULT '' COMMENT '关键字',
`path` varchar(100) NOT NULL DEFAULT '' COMMENT '图片封面',
`description` char(255) NOT NULL DEFAULT '' COMMENT '描述',
`is_show` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '是否显示 1是 0否',
`is_top` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否置顶 1是 0否'
`click` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击数',
`cid` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '分类id',
PRIMARY KEY (`aid`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
上述SQL语句创建了一个名为article
的表,包含以下字段:
aid
:文章表主键,使用int
数据类型,长度为10,使用unsigned
表示非负数。title
:标题,使用char
数据类型,长度为100个字符,非空字段。content
:文章内容,使用mediumtext
数据类型,非空字段。url
:链接,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。keywords
:关键字,使用varchar
数据类型,最大长度为255个字符,默认为空字符串。path
:图片封面,使用varchar
数据类型,最大长度为100个字符,非空字段。description
:描述,使用char
数据类型,长度为255个字符,默认为空字符串。is_show
:是否显示,使用tinyint
数据类型,范围是0到1,非空字段,默认为1。is_top
:是否置顶,使用tinyint
数据类型,范围是0到1,非空字段,默认为0。click
:点击数,使用int
数据类型,长度为10,非空字段,默认为0。cid
:分类id,使用tinyint
数据类型,范围是0到255,非空字段,默认为0。PRIMARY KEY (
aid)
:aid
字段作为主键。
数据库引擎选择了InnoDB,自增起始值为18,默认字符集为utf8。
标签表
sql
CREATE TABLE `tag` (
`tid` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '标签主键',
`tname` varchar(10) NOT NULL DEFAULT '' COMMENT '标签名',
PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
上述SQL语句创建了一个名为tag
的表,包含以下字段:
tid
:标签主键,使用int
数据类型,长度为10,使用unsigned
表示非负数。tname
:标签名,使用varchar
数据类型,最大长度为10个字符,非空字段。
该表用于存储文章的标签信息,每个标签对应一条记录。其中,tid
字段作为主键。
数据库引擎选择了InnoDB,自增起始值为21,默认字符集为utf8。
内容标签关联表
sql
CREATE TABLE `article_tag` (
`aid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章id',
`tid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '标签id'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
上述SQL语句创建了一个名为article_tag
的表,用于存储内容和标签之间的关联关系。
该表包含以下字段:
aid
:文章id,使用int
数据类型,长度为10,默认值为0,非空字段。tid
:标签id,使用int
数据类型,长度为10,默认值为0,非空字段。
通过这个关联表,可以实现多对多关系,即一个内容可以有多个标签,一个标签可以对应多篇内容。这样的设计可以方便地查询某篇内容的全部标签,或者查询某个标签对应的所有内容。
用户表
sql
CREATE TABLE `oauth_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`uid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '关联的本站用户id',
`type` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '类型 1:QQ 2:新浪微博 3:豆瓣 4:人人 5:开心网',
`nickname` varchar(30) NOT NULL DEFAULT '' COMMENT '第三方昵称',
`head_img` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
`openid` varchar(40) NOT NULL DEFAULT '' COMMENT '第三方用户id',
`access_token` varchar(255) NOT NULL DEFAULT '' COMMENT 'access_token token',
`create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '绑定时间',
`last_login_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后登录时间',
`last_login_ip` varchar(16) NOT NULL DEFAULT '' COMMENT '最后登录ip',
`login_times` int(6) unsigned NOT NULL DEFAULT '0' COMMENT '登录次数',
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态',
`email` varchar(255) NOT NULL DEFAULT '' COMMENT '邮箱',
`is_admin` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否是admin',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
该表包含以下字段:
id
:主键id,使用int
数据类型,长度为10,使用unsigned
表示非负数。uid
:关联的本站用户id,使用int
数据类型,长度为10,默认值为0。type
:类型,使用tinyint
数据类型,长度为3,默认值为1。1表示QQ登录,2表示新浪微博登录,3表示豆瓣登录,4表示人人登录,5表示开心网登录。nickname
:第三方昵称,使用varchar
数据类型,长度为30个字符,非空字段。head_img
:头像,使用varchar
数据类型,长度为255个字符,非空字段。openid
:第三方用户id,使用varchar
数据类型,长度为40个字符,非空字段。access_token
:access_token token,使用varchar
数据类型,长度为255个字符,非空字段。create_time
:绑定时间,使用int
数据类型,长度为10,默认值为0。last_login_time
:最后登录时间,使用int
数据类型,长度为10,默认值为0。last_login_ip
:最后登录ip,使用varchar
数据类型,长度为16个字符,非空字段。login_times
:登录次数,使用int
数据类型,长度为6,默认值为0。status
:状态,使用tinyint
数据类型,长度为1,默认值为1。1表示启用,0表示禁用。email
:邮箱,使用varchar
数据类型,长度为255个字符,非空字段。is_admin
:是否是admin,使用tinyint
数据类型,长度为1,默认值为0。1表示是管理员,0表示不是。
其中,id
字段作为主键。
数据库引擎选择了InnoDB,自增起始值为2,默认字符集为utf8。
小总结:
根据创建表的SQL语句,knowledge
表和category
表之间存在如下关联:
category
表的kid
字段与knowledge
表的kid
字段相关联,用于表示一个分类属于哪一个知识库。这是一个外键关联,通过kid
字段建立关联,kid
字段在category
表中是一个非空字段。
可以根据这个关联,通过查询category
表中的kid
字段,找到对应的知识库。这可以用于在知识库页面显示所属分类,或者根据知识库获取对应的分类信息。
需要注意的是,以上关联是在表结构中定义了关联字段的基础上建立的。在使用这两个表进行实际的数据库操作时,可以通过关联字段实现数据查询、插入、更新等操作。
tag
表存储了所有的标签信息,每个标签对应一条记录。tid
字段作为标签的主键,用于唯一标识一个标签。article_tag
表用于建立文章和标签之间的关联关系。它包含了aid
和tid
两个字段,分别代表文章id和标签id。通过该关联表,可以实现多对多的关系,一个文章可以有多个标签,一个标签也可以对应多篇文章。oauth_user
表用于存储第三方登录用户的信息。该表包含了与第三方登录相关的字段,如第三方登录的类型、昵称、头像等都可以存储在该表中。还包含了用户的相关信息,如邮箱、最后登录时间等。
通过这些数据表的关联设计,我们可以进行以下操作:
- 添加新的标签:可以向
tag
表中插入新的标签记录,自动生成唯一的tid
作为主键。 - 关联文章和标签:可以向
article_tag
表中插入新的记录,指定对应的aid
和tid
,以建立文章和标签之间的关联关系。 - 查询某篇文章的标签:可以通过
article_tag
表根据文章id(aid
字段)查找对应的标签id(tid
字段),然后再通过tag
表查询所对应的标签信息。 - 查询某个标签对应的所有文章:可以通过
article_tag
表根据标签id(tid
字段)查找对应的文章id(aid
字段),然后再通过文章表查询所对应的文章信息。 - 存储第三方登录用户信息:可以将第三方登录用户的相关信息存储在
oauth_user
表中,并与本站的用户信息进行关联。
通过这些关联和操作,我们可以构建一个具有标签分类和第三方登录功能的知识库博客。通过标签分类,可以方便地查找和归类文章;通过第三方登录(如qq、微信),可以提供更多的登录选项和个性化的用户体验。
NestJs应用
接口设计
下面是之前设计的小部分接口,供参考:
这里再说下关于一对多和多对多的知识库生成
Knowledge表:
- 一个知识库,都有独立的一套分类 1对1
- 一个知识库,对应多文章 1对N
- 一个知识库,对应多标签 1对N
那么设计知识库表的时候我们可以这样映射:
数据库会生成这样一个表:
Category表:
多个分类对应一个知识库
Tag表
多个标签对应一个知识库
剩余的就不贴图了
当使用 TypeORM 注册数据库连接和实体后,就可以使用 NestJS 中的服务和控制器来进行数据的增删改查操作
因为边幅有限,所以登录鉴权以及控制器、业务层的实现,下一篇文章做总结。