大模型之路7-3:中国人都会喜欢的知识库——中华诗词知识库(同步Github)数据Schema设计
📊 中华诗词知识库 · 第三章:数据结构设计
Knowledge Base of Chinese Poetry (KBCP) — Chapter 3: Schema
🌟GitHub 开源地址:https://github.com/liang1057/Knowledge-Base-of-Chinese-Poetry
🌟 如果资源对你有帮助,欢迎 Star 支持!
📥 JSON数据下载:https://download.csdn.net/download/sdust_dx/92826598
🎯 前言
前两章讲到了数据和数据清洗,本章将正式进入数据层的核心设计——Schema(模式)定义。
中华诗词的数据结构有一个显著特点:半结构化与非结构化并存。一首诗的正文是自由文本,但体裁、格律、意象、情感等属性又需要高度标准化。如果 Schema 设计过于简单,后续 RAG 检索和知识图谱构建将举步维艰;如果设计过于臃肿,又会给数据清洗和入库带来巨大成本。
因此,本章的核心目标是:在“文学自由表达”与“机器可理解”之间找到最佳平衡点。
🗂️ 一、总体的数据结构:五表联动与词汇标准化
整个知识库的底层采用 SQLite 作为关系型存储引擎,Schema 层通过 ORM 风格封装了 5 张核心表,形成如下关系:
| 表名 | 职责 | 关键关联 |
|---|---|---|
poem |
诗词作品主表 | 外键关联 dynasty、author |
author |
诗人/作者信息 | 通过 dynasty_id 关联朝代 |
dynasty |
朝代元数据 | 独立基础表,统一时间轴 |
vocab |
受控词汇表 | 全库标签体系的标准化源头 |
myschema |
元数据记录 | 记录 Schema 自身版本与变更 |
注意:所有标签类字段(如 genre、form、theme、style、emotion 等)均不存储自由文本,而是指向 vocab 表的标准化键值。这为后续的多义词消歧、同义词扩展和向量检索打下了基础。这也是我重构了两次得到的经验。
🏗️ 二、核心表
2.1 诗词表 table_poem — 这也是全库最复杂的实体
poem 表是知识库的核心,字段设计遵循**“分层存储、逐层解析”**的原则。经过多次完善,已经达到了 40+ 个字段,将其划分为 8 个逻辑层:
分层设计思路:
| 层级 | 设计意图 | 典型应用 |
|---|---|---|
| 基础信息 | 唯一标识与溯源 | 全库去重、跨库对齐 |
| 结构化内容 | 将自由文本拆解为机器可处理的单元 | 按句检索、格律校验、文本比对 |
| 文学属性 | 建立体裁与格律的标准化分类 | 筛选“所有七言律诗”、检索“平水韵作品” |
| 扩展信息 | 保留人类可读的释义与背景 | RAG 生成回答时的引用素材 |
| 标签体系 | 多维度语义标注 | 向量检索的元数据过滤、主题冲突检测 |
| 检索优化 | 倒排索引与 faceted search 支持 | “春天的离别诗”“涉及长安的边塞诗” |
| RAG 相关 | 为向量库与知识图谱预留接口 | 相似作品推荐、引用溯源 |
| 管理字段 | 数据治理与版本控制 | 审核流程、增量更新 |
class table_poem(EntityBase):
def __init__(self):
super().__init__()
self.SetTableName('poem')
# 1. 基础信息层
self.AddColumn(colName='poem_id', colType='text', ...)
self.AddColumn(colName='title', colType='text', ...)
self.AddColumn(colName='author', colType='text', ...)
self.AddColumn(colName='dynasty', colType='text', ...)
# 2. 结构化内容层
self.AddColumn(colName='content', colType='text', ...)
self.AddColumn(colName='paragraphs', colType='varchar', ...)
self.AddColumn(colName='sentences', colType='varchar', ...)
self.AddColumn(colName='line_count', colType='int', ...)
self.AddColumn(colName='char_count', colType='int', ...)
# 3. 文学属性层
self.AddColumn(colName='genre', colType='text', ...) # 诗/词/曲/赋
self.AddColumn(colName='form', colType='varchar', ...) # 五言绝句/七言律诗...
self.AddColumn(colName='meter', colType='text', ...) # 平水韵/中华新韵
# 4. 扩展信息层
self.AddColumn(colName='description', colType='text', ...)
self.AddColumn(colName='translation', colType='text', ...)
self.AddColumn(colName='appreciation', colType='text', ...)
self.AddColumn(colName='background', colType='text', ...)
# 5. 知识增强与标签体系层
self.AddColumn(colName='theme', colType='varchar', ...)
self.AddColumn(colName='style', colType='varchar', ...)
self.AddColumn(colName='emotion', colType='varchar', ...)
self.AddColumn(colName='imagery', colType='varchar', ...)
self.AddColumn(colName='allusions', colType='varchar', ...)
# 6. 检索优化层
self.AddColumn(colName='keywords', colType='varchar', ...)
self.AddColumn(colName='season', colType='text', ...)
self.AddColumn(colName='festival', colType='text', ...)
self.AddColumn(colName='places_involved', colType='varchar', ...)
self.AddColumn(colName='people_involved', colType='varchar', ...)
# 7. RAG 相关层
self.AddColumn(colName='citation_text', colType='text', ...)
self.AddColumn(colName='aliases', colType='varchar', ...)
self.AddColumn(colName='related_poem_ids', colType='varchar', ...)
# 8. 管理层
self.AddColumn(colName='created_at', colType='text', ...)
self.AddColumn(colName='data_version', colType='text', ...)
self.AddColumn(colName='review_status', colType='text', ...)
几个关键字段的深入说明:
poem_id编码规则:采用朝代编号-作者编号-诗词编号的三段式结构,例如T-12345-678901。这种设计天然支持按朝代、按作者分片,且无需 JOIN 即可快速定位。paragraphs与sentences:词有上下阕,曲有牌调,诗有联句。保留段落切分和句子切分两套数组,既方便前端渲染,也方便 NLP 模型做句级嵌入。citation_text:RAG 输出时必须给出可溯源的原文。该字段强制保留标准原文(含标点),避免在检索-生成链路中出现“篡改原文”的幻觉。
2.2 作者表 table_author — 别名体系
诗人往往有名、字、号、谥号、别称等多重身份标识。如果把这些混在一个字段里,检索“东坡居士”时将无法关联到“苏轼”。
class table_author(EntityBase):
def __init__(self):
self.SetTableName('author')
self.AddColumn(colName='author_id', colType='text', ...)
self.AddColumn(colName='name', colType='text', ...) # 标准名:苏轼
self.AddColumn(colName='courtesy_name', colType='text', ...) # 字:子瞻
self.AddColumn(colName='art_name', colType='varchar', ...) # 号:['东坡居士']
self.AddColumn(colName='other_names', colType='varchar', ...)# 别名:['苏东坡',...]
self.AddColumn(colName='style_summary', colType='varchar', ...)
self.AddColumn(colName='major_themes', colType='varchar', ...)
self.AddColumn(colName='common_imagery', colType='varchar', ...)
设计要点:other_names 和 art_name 均采用 varchar(数组序列化)存储。在入库阶段,通过 OpenCC 进行繁简转换预处理,确保“蘇軾”与“苏轼”指向同一实体。
2.3 朝代表 table_dynasty — 时间轴统一
class table_dynasty(EntityBase):
def __init__(self):
self.SetTableName('dynasty')
self.AddColumn(colName='dynasty_id', colType='text', ...) # 如 'T'
self.AddColumn(colName='name', colType='text', ...) # '唐'
self.AddColumn(colName='another_name', colType='varchar', ...)# ['李唐','大唐']
self.AddColumn(colName='start_year', colType='int', ...)
self.AddColumn(colName='end_year', colType='int', ...)
特别说明:name 字段标注为“用于诗词的”标准朝代名。例如“先秦”作为一个统一朝代节点,涵盖夏、商、周、春秋、战国等子时期,避免在诗词分类上过度碎片化。
2.4 词汇表 table_vocab — 全库可控的“语义字典”
这是整个知识库标准化程度最高的表,也是后续 RAG 检索质量的决定性因素:
class table_vocab(EntityBase):
def __init__(self):
self.SetTableName('vocab')
self.AddColumn(colName='vocab_id', colType='text', ...)
self.AddColumn(colName='name', colType='text', ...) # 标准类目名,如"主题"
self.AddColumn(colName='key', colType='text', ...) # 键:如 "theme"
self.AddColumn(colName='value', colType='text', ...) # 值:如 "山水"
为什么必须独立建表?
以 theme(主题)为例,如果允许自由录入,会出现“山水”“山水田园”“自然山水”等多种写法,导致向量检索时同主题无法聚合。通过 vocab 表强制收敛,所有主题必须从预设词表中选取,保证了** faceted search 的精确性**。这也是我做数据治理和数据标准化工作积累的经验。
2.5 元数据记录表 table_myschema — Schema 的自描述
class table_myschema(EntityBase):
def __init__(self):
self.SetTableName('myschema')
# 记录每个表的字段中文名、键名、类型
self.AddColumns(colNames=['schema_id','table_name','column_label',
'column_name','type'], ...)
这张表看似“元数据的元数据”,但在实际项目中非常有用:当后续通过代码自动生成前端表单、API 文档或向量库字段映射时,可以直接读取 myschema 获得人类可读的字段说明,避免硬编码。
🔧 三、工程实现亮点
3.1 EntityBase 的 ORM 风格封装
所有表均继承自 EntityBase,通过 AddColumn / AddColumns 链式调用完成字段注册。这种设计的优势在于:
- 自文档化:字段定义即注释,源码即 Schema 文档。
- 可扩展:新增字段只需追加一行,不需要去搞SQL。
- 驱动生成:可基于
EntityBase的元数据自动生成建表 SQL、Pydantic Model 和前端表单。
3.2 OpenCC 的预处理集成
from opencc import OpenCC
sc2tc = OpenCC('s2t') # 简体转繁体
tc2sc = OpenCC('t2s') # 繁体转简体
在数据入库管道中,所有 title、content、author 等字段均会经过繁简双向转换校验。这确保了无论原始数据源是《全唐诗》的繁体版本还是现代整理的简体版本,最终都能归一化处理。
3.3 字段类型的刻意选择
| 类型 | 使用场景 | 原因 |
|---|---|---|
text |
大段文本 | SQLite 的 TEXT 无长度限制,适合正文、赏析 |
varchar |
数组/列表 | 存储 JSON 序列化的标签数组,如 ["月","霜"] |
int |
统计值 | 行数、字数、年份,便于范围查询 |
🧩 四、与 RAG 架构的衔接
当前 Schema 中,与 RAG 直接相关的字段已预留了三个层次:
- 文本层:
content、paragraphs、sentences→ 用于向量嵌入(Embedding) - 元数据层:
theme、style、emotion、imagery→ 用于向量检索时的过滤条件(Metadata Filtering) - 关系层:
related_poem_ids→ 用于知识图谱构建和跨文档主题关联
💡 预留说明:源码中注释掉的
related、similar、related_author等字段,将在第四章(向量库设计)中决定是保留为关系表,还是直接存入向量数据库的 payload。
📝 五、本章小结
| 设计目标 | 实现方式 |
|---|---|
| 标准化 | vocab 受控词表 + 全库唯一编号 |
| 结构化 | 正文/段落/句子三级切分 + 行数字数统计 |
| 可扩展 | EntityBase 链式字段注册 + 版本管理字段 |
| RAG 友好 | 标签体系 + 引用文本 + 相关作品 ID |
| 多语言兼容 | OpenCC 繁简转换 + 别名体系 |
下一章,将会介绍诗词的Web可视化以及使用大数据模型进行的智能化分析。
🌟 如果本文对你有帮助,欢迎 Star 支持!
GitHub 开源地址:https://github.com/liang1057/Knowledge-Base-of-Chinese-Poetry
CSDN 专栏:中华诗词知识库(KBCP)系列文章
📧 交流邮箱:liang1057@163.com
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
更多推荐
所有评论(0)