论如何设计博客分类标签系统

简介:

本文描述了这个博客背后归档系统的设计与实现思路。

逻辑模型设计

通常博客所用的归档方式有三种:

  • 按发布时间归档
  • 分类体系
  • 标签体系
    这三种归档体系是可以同时存在的,而且这样的设计也非常常见。
    其中按时间归档实在是Trivial,而且归档逻辑性也相对较弱,故在此略去不提。

通常分类与标签体系最大的区别在于,文章和分类是多对一的关系,而标签和文章是多对多的关系。
实际上在使用中,我发现分类确实不如标签好用。
在使用OneNote整理笔记的时候,经常出现一类很让人头疼的Delimma。比如,用Python做的可视化演示,究竟是应当放入Python分类中呢?还是放在可视化分类中呢?
避免这个问题,需要分类设计做到完全正交,然而真正能做到完全正交的分类体系又往往不甚实用……。更重要的一点是,每当我检索笔记的时候,往往是通过类似标签形式的关键词搜索去定位文章的……分类体系更是显得累赘了……

不过完全不要分类体系好不好?当然也不好,当然,多级分类应该拍扁成一级分类,这样分类就可以做成一个字段放入文章表中了。

所以在我看来,博客的归档系统,应当以标签系统为主,分类系统为辅。
分类系统必须是扁平的,不可有过多的类目,且尽量做到正交。
我的博客目前拟采用以下分类

 
  1. INSERT INTO categories (cate_name)
  2. VALUES ('未分类'), ('随笔文章'), ('生活记录'), ('工作记录'), ('文档剪藏'), ('读书笔记'), ('前端戏法'), ('后端杂技'), ('算法心得'), ('数据库'), ('部署运维'),('知识积累'), ('游戏杂谈');

而标签就会显得比较随意了。

数据模型设计

传统方法

传统上,按照数据库设计理论Blabla,应当这样设计:

 
  1. ------------- 基础表定义 -------------
  2. -- 登录信息表
  3. CREATE TABLE IF NOT EXISTS login (
  4. user_id SERIAL PRIMARY KEY,
  5. email TEXT NOT NULL UNIQUE,
  6. hashed_password TEXT NOT NULL
  7. );
  8. -- 用户信息表
  9. CREATE TABLE IF NOT EXISTS users (
  10. user_id INTEGER PRIMARY KEY REFERENCES login (user_id),
  11. email TEXT NOT NULL UNIQUE,
  12. name TEXT NOT NULL,
  13. avatar TEXT
  14. );
  15. -- 博文分类表
  16. CREATE TABLE IF NOT EXISTS categories (
  17. cate_id SERIAL PRIMARY KEY,
  18. cate_name TEXT NOT NULL UNIQUE
  19. );
  20. -- 博客文章表
  21. CREATE TABLE IF NOT EXISTS articles (
  22. article_id SERIAL PRIMARY KEY,
  23. user_id INT NOT NULL REFERENCES users (user_id),
  24. title TEXT NOT NULL,
  25. content TEXT NOT NULL,
  26. description TEXT,
  27. thumb TEXT,
  28. cate_id INTEGER NOT NULL REFERENCES categories (cate_id) DEFAULT 1,
  29. private BOOLEAN DEFAULT FALSE,
  30. ctime TIMESTAMP NOT NULL DEFAULT current_timestamp,
  31. mtime TIMESTAMP NOT NULL DEFAULT current_timestamp,
  32. read_cnt INT DEFAULT 0,
  33. upvote_cnt INT DEFAULT 0
  34. );
  35. -- 标签表
  36. CREATE TABLE IF NOT EXISTS tags (
  37. tag_id SERIAL PRIMARY KEY,
  38. tag_name TEXT NOT NULL UNIQUE
  39. );
  40. -- 标签映射表
  41. CREATE TABLE IF NOT EXISTS tag_mapping (
  42. article_id INTEGER REFERENCES articles (article_id) ON DELETE CASCADE,
  43. tag_id INTEGER REFERENCES tags (tag_id),
  44. PRIMARY KEY (article_id, tag_id)
  45. );
  46. ---------------- 复合类型定义 ----------------
  47. -- 文章类型,包括文章的详细信息
  48. CREATE TYPE article AS (
  49. user_id INTEGER,
  50. cate_id INTEGER,
  51. article_id INTEGER,
  52. title TEXT,
  53. content TEXT,
  54. description TEXT,
  55. thumb TEXT,
  56. private BOOLEAN,
  57. ctime TIMESTAMP,
  58. mtime TIMESTAMP,
  59. read_cnt INTEGER,
  60. upvote_cnt INTEGER,
  61. cate_name TEXT,
  62. email TEXT,
  63. name TEXT,
  64. avatar TEXT,
  65. tags JSONB
  66. );
  67. -- 文章摘要,除了content字段外的所有信息
  68. CREATE TYPE article_entry AS (
  69. user_id INTEGER,
  70. cate_id INTEGER,
  71. article_id INTEGER,
  72. title TEXT,
  73. description TEXT,
  74. thumb TEXT,
  75. private BOOLEAN,
  76. ctime TIMESTAMP,
  77. mtime TIMESTAMP,
  78. read_cnt INTEGER,
  79. upvote_cnt INTEGER,
  80. cate_name TEXT,
  81. email TEXT,
  82. name TEXT,
  83. avatar TEXT,
  84. tags JSONB
  85. );
  86. -- 标签信息
  87. CREATE TYPE tag AS (
  88. tag_id INTEGER,
  89. tag_name TEXT,
  90. article_cnt INTEGER,
  91. articles INTEGER []
  92. );
  93. -- 类目信息
  94. CREATE TYPE category AS (
  95. cate_id INTEGER,
  96. cate_name TEXT,
  97. article_cnt INTEGER,
  98. articles INTEGER []
  99. );
  100. -- 用户信息
  101. CREATE TYPE user_entry AS (
  102. user_id INTEGER,
  103. email TEXT,
  104. hashed_password TEXT,
  105. nickname TEXT,
  106. avatar TEXT
  107. );

这样设计的好处,当时只要对映射表轻松地聚合,就可以实现查询文章所有的标签和查询标签对应的所有文章,正查倒查效率都很高。当然坏处就是特么的查个标签最后我要Join三张表……

JSON方法

事实上,如果把标签作为一个Json字段放在文章表里,就可以省却很多这类破事了。
尤其是当PostgreSQL支持JSON索引的时候,直接通过where子句筛选标签字段,同样可以实现传统方法的功能,而且不需要额外的Join了。
不过后来,我发现JSON的设计还是不给力,因为如果我想统计每个标签下面究竟挂着多少文章,JSON的设计就蛋疼了。仔细想想,关系型数据库的崛起确实是因为它的确具有优越性。当然,最后定义了视图里面,还是采用了一些JSON字段的。

目录
相关文章
|
JavaScript 中间件 网络架构
Nuxt.js:用 Vue.js 打造服务端渲染应用程序(一)
Nuxt.js:用 Vue.js 打造服务端渲染应用程序
|
JavaScript 前端开发 Web App开发
【网站开发必备】——12款响应式 Lightbox(灯箱)效果插件
  灯箱效果(Lightbox)是网站中最常用的效果之一,用于实现类似模态对话框的效果。网络上各种 Lightbox 插件琳琅满目,随着响应式设计(Respnsive Design)的发展,这一先进理念也被引入了 Lightbox 插件之中。
2669 1
|
7月前
|
Java
Idea自动生成注释
Idea自动生成注释
192 6
Idea自动生成注释
|
存储 搜索推荐 数据库
软件系统【标签tag功能】的两种数据库设计
软件系统中的标签功能可采用两种数据库设计。方案一,文章和Tag各一表,Tag信息存储在文章表内(`tags`和`tagids`字段),优点是模型简单,但查询效率低且易引发数据冗余和一致性问题。方案二,增加Tagmap表,用于存储标签-文章映射,利于索引查询和数据更新,适用于高效率需求,但结构更复杂。
661 0
软件系统【标签tag功能】的两种数据库设计
|
网络协议 应用服务中间件 网络安全
阿里云免费SSL申请流程(白嫖20张SSL免费证书)2024年新版教程
本文详述了2024年最新的阿里云免费SSL证书申请流程。用户可通过阿里云数字证书管理服务控制台一键申请最多20张免费单域名SSL证书,每张证书有效期为3个月。首先登录控制台,选择“SSL证书管理”下的“个人测试证书”,同意协议并完成购买流程。之后需创建证书、输入域名等信息并进行域名验证。验证方法包括手动DNS验证、域名授权自动化验证或文件验证。完成验证后,等待审核通过即可下载适用于不同服务器类型的SSL证书。请注意,阿里云免费SSL证书到期后不支持续费,需重新申请。了解更多详情,请访问阿里云官方SSL证书页面。
|
SQL 关系型数据库 MySQL
MySQL模糊查询二三事
在实际应用中,根据需求和实际数据情况,选择合适的模糊查询方法并优化查询模式,是确保查询效率和准确性的关键。复杂的查询模式往往需要详细的测试和调优,以达到最佳的性能与响应时效。
610 4
|
运维 Kubernetes 安全
推荐3个开源好用的堡垒机
【7月更文挑战第11天】
4184 0
推荐3个开源好用的堡垒机
|
NoSQL 数据库 Redis
3种高效的Tags标签系统数据库设计方案分享
需求背景 目前主流的博客系统、CMS都会有一个TAG标签系统,不仅可以让内容链接的结构化增强,而且可以让文章根据Tag来区分。相比传统老式的Keyword模式,这种Tag模式可以单独的设计一个Map的映射表来增加系统的负载和查询的效率。
14305 0
|
消息中间件 存储 负载均衡
Kafka高可用性指南:提高数据一致性和集群容错能力!
**Kafka高可用性概览** - 创建Topic时设置`--replication-factor 3`确保数据冗余和高可用。 - 分配角色:Leader处理读写,Follower同步数据,简化管理和客户端逻辑。 - ISR(In-Sync Replicas)保持与Leader同步的副本列表,确保数据一致性和可靠性。 - 设置`acks=all`保证消息被所有副本确认,防止数据丢失,增强一致性。 - 通过这些机制,Kafka实现了分布式环境中的数据可靠性、一致性及服务的高可用性。
1280 0
|
算法
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
458 0