去提问»
提问背景 Question:
我明白了,加二张表,一是词条表,二是词条与内容的关联表。只要词条判断是正常有效了,就自动加上这个词条的链接

百科词条库与关联表设计

发布时间:2026-08-18 12:54 👁️ 阅读:2

你的思路非常清晰,这正是构建大型百科/知识库系统最标准、最健壮的**“多对多(Many-to-Many)”**架构设计。通过引入独立的“词条表”和“关联表”,你不仅能够完美实现内链网络,还能保证极高的查询性能和易维护性。

下面为你梳理这套方案的数据库设计、核心匹配算法以及自动化工作流


一、 数据库表结构设计

1. 词条表 (terms)

存储所有被提炼出来的词条,以及它们本身的释义、状态。

CREATE TABLE `terms` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(100) NOT NULL UNIQUE,          -- 词条名称(如:红茶,必须唯一)
  `description` TEXT NULL,                     -- AI生成的词条释义/摘要
  `status` TINYINT DEFAULT 0,                  -- 状态:0-草稿/未生成释义,1-已生效(可外链)
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. 词条与内容关系表 (term_relations)

用于记录“哪篇文章包含了哪些词条”。

CREATE TABLE `term_relations` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `content_id` INT NOT NULL,                   -- 内容ID
  `term_id` INT NOT NULL,                      -- 词条ID
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY `unique_content_term` (`content_id`, `term_id`), -- 联合唯一索引防止重复
  FOREIGN KEY (`content_id`) REFERENCES `contents`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`term_id`) REFERENCES `terms`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、 核心难题:重叠词条(“冰红茶”与“红茶”)的匹配算法

如果在内容中直接用简单的 replace("红茶", "<a href...>"),会导致 冰红茶 被拆解为 冰<a href...>红茶</a>,这会导致 HTML 标签错乱,体验极差。

解决方案:最长匹配优先 + 占位符替换法

  1. 获取待匹配词条列表
    terms 表中取出所有 status = 1(已生效)的词条,按字符长度降序排序(例如:冰红茶(3字)排在 红茶(2字)前面)。
  2. 首次正则占位(不直接替换为 HTML)
    按照排序后的顺序遍历词条,使用正则表达式进行匹配。匹配成功后,先替换为一个唯一的占位符(如 {%TERM_ID_12%}),而不是 <a> 标签。这样在匹配短词 红茶 时,由于 冰红茶 已经变成了 冰{%TERM_ID_12%},所以绝对不会发生二次冲突。
  3. 二次还原为链接
    遍历完所有词条后,将文本中的 {%TERM_ID_XX%} 统一还原替换为 <a href="/terms/XX">原词</a>

三、 自动化工作流(静态化渲染提升 SEO)

为了避免每次用户访问文章时都去用 CPU 做正则匹配,强烈建议采用**“静态预编译”**方案:

  1. 内容发布时

    • 用户发布或 AI 生成文章《如何泡好一杯冰红茶》。
    • 系统后台触发异步任务:检索词条库中已激活(status=1)的词条。
    • 运行上述“最长匹配优先算法”,计算出本文命中了哪些词条(如“冰红茶”、“茶具”)。
    • 将关联记录写入 term_relations 表。
    • 生成带 <a> 标签的 HTML 内容,存入文章表的 compiled_content(编译后内容)字段中,直接用于前端展示。
  2. 当新词条被激活/生成时

    • 例如,词条“红茶”以前是草稿(status=0),现在 AI 帮它生成了释义,状态变为了 status=1
    • 触发订阅事件:在 contents 表中进行模糊匹配,找出包含“红茶”字样的文章。
    • 重新计算并更新这些文章的 term_relations 关联,并重新编译生成最新的 compiled_content

通过这种“双表关联+静态编译”的模式,既保护了服务器的性能,又让搜索引擎爬虫能顺着静态的 <a> 标签完美抓取整站内链,SEO 效果直接拉满!