GTE-Base-ZH数据库课程设计实现文本语义相似度检索模块你是不是还在为数据库课程设计做什么而发愁是做一个简单的图书管理系统还是搞一个学生信息管理这些项目虽然经典但总觉得少了点新意写在简历上也不够亮眼。今天咱们来点不一样的。我们不只满足于增删改查而是要给传统的数据库加上一点“智能”。想象一下你的数据库不仅能根据关键词精确匹配还能理解你输入句子的“意思”找到那些意思相近但用词不同的记录。比如你搜索“如何学习编程”它能把“编程入门指南”、“代码学习技巧”这些相关但字面不匹配的内容都找出来。这就是语义相似度检索的魅力。而实现它的核心就是一个能将文本转化为数学向量一串数字的模型。我们这次要用的就是专为中文优化的GTE-Base-ZH模型。这个课程设计就是要教你如何把这个模型“塞进”你的MySQL数据库里打造一个具备语义检索能力的智能应用。整个过程就像搭积木设计存向量的表、写脚本把文字变成向量、最后用SQL算出最相似的记录。跟着做下来你不仅能巩固数据库知识还能亲手摸到AI落地的边儿绝对是一个既有技术深度又有实用价值的项目。1. 项目准备理解核心概念与工具在动手敲代码之前咱们先花几分钟把几个核心概念理清楚。别担心不用复杂的数学公式咱们用大白话讲明白。文本向量Embedding你可以把它想象成给一句话拍一张“数学身份证”。模型会把一句话比如“我喜欢吃苹果”转换成一长串有规律的数字比如[0.1, -0.3, 0.8, ... , 0.02]通常是384或768个数字。这个“身份证”的奇妙之处在于意思相近的句子它们的数字串在数学空间里的“距离”会很近意思相反的句子距离就很远。我们后续的检索其实就是计算和比较这些“身份证”之间的距离。余弦相似度Cosine Similarity这是我们衡量两个向量即两个“数学身份证”相似程度的尺子。它的计算结果在-1到1之间。越接近1说明两个向量的方向越一致语义越相似越接近0或负数则说明越不相关。计算这个值我们之后会用到一点简单的SQL函数。GTE-Base-ZH模型这是咱们项目的“发动机”。它是一个开源的中文文本向量生成模型特点就是专门针对中文语料训练过效果不错而且模型大小适中在普通电脑上也能跑起来。我们不需要训练它只需要调用它把文本输进去把向量拿出来就行。整体流程预览数据库层在MySQL里我们不仅要存文本比如文章标题、内容还要新增一个字段来存它的“向量身份证”。应用层写一个Python脚本它的工作就是调用GTE模型把一篇篇文本变成向量然后存回数据库。检索层写一个SQL查询这个查询能计算用户输入句子的向量与数据库中所有向量之间的余弦相似度并按相似度高低返回结果。明白了这些我们的工具箱也要准备好。你需要有MySQL数据库5.7或8.0版本均可。Python 3.8以上的环境。一个代码编辑器比如VSCode或PyCharm。接下来我们就从设计数据库表开始。2. 第一步设计数据库表结构传统的文章表可能只包含id、title、content、create_time这几个字段。现在我们要为它增加一个“智能心脏”——存储文本向量的字段。假设我们的项目是一个“智能知识库”用于存储技术文章。下面是一个推荐的表结构设计CREATE TABLE knowledge_articles ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID, title varchar(255) NOT NULL COMMENT 文章标题, content text COMMENT 文章正文内容, title_vector JSON DEFAULT NULL COMMENT 标题文本向量使用JSON类型存储, content_vector JSON DEFAULT NULL COMMENT 内容摘要向量可选使用JSON类型存储, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), KEY idx_create_time (create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT知识文章表包含语义向量字段;关键字段解释title_vector和content_vector这是核心创新点。我们使用MySQL的JSON数据类型来存储向量数组。例如GTE-Base-ZH模型生成一个384维的向量它会以JSON数组的形式[0.12, -0.05, ..., 0.33]存储在这里。用JSON类型的好处是MySQL提供了一些函数如JSON_EXTRACT可以方便地处理数组为后续计算相似度做准备。为什么存两个这是一种设计策略。通常标题的语义更集中计算相似度时更快、更精准。内容向量更全面但计算开销大。你可以根据实际需求选择只存标题向量或者都存。课程设计中建议先实现title_vector。小提示在真正的生产环境中面对海量数据直接使用MySQL计算向量相似度可能会比较慢。那时会引入专门的向量数据库如Milvus、Pinecone。但作为课程设计用MySQL完全足够它能让我们更聚焦于理解整个语义检索的流程和原理。表建好后你可以先插入几条示例数据注意vector字段先留空INSERT INTO knowledge_articles (title, content) VALUES (Python编程入门教程, 本文介绍Python的基本语法、数据类型和循环控制...), (MySQL数据库安装与配置, 详细讲解如何在Windows和Mac系统下安装MySQL...), (机器学习基础概念, 什么是机器学习监督学习和无监督学习有什么区别...), (如何使用Git进行版本控制, 学习Git的基本命令如clone, add, commit, push...);3. 第二步编写Python脚本生成文本向量现在我们需要一个“翻译官”把中文文本翻译成向量。这个翻译官就是我们的Python脚本。首先安装必要的Python库pip install torch transformers pymysql接下来创建脚本文件generate_embeddings.pyimport torch from transformers import AutoModel, AutoTokenizer import pymysql import json import sys # 1. 加载GTE-Base-ZH模型与分词器 print(正在加载GTE-Base-ZH模型这可能需要一点时间...) model_name thenlper/gte-base-zh # 使用Hugging Face上的模型 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name) print(模型加载成功) # 将模型设置为评估模式并放到GPU上如果有的话 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) model.eval() def get_embedding(text): 将单条文本转换为向量 if not text or text.strip() : return None try: # 对文本进行编码 inputs tokenizer(text, paddingTrue, truncationTrue, return_tensorspt, max_length512) inputs {k: v.to(device) for k, v in inputs.items()} # 通过模型获取输出并计算均值池化得到句子向量 with torch.no_grad(): outputs model(**inputs) # 取最后一层隐藏状态并用注意力掩码进行均值池化 attention_mask inputs[attention_mask] last_hidden_state outputs.last_hidden_state # 扩展注意力掩码的维度以便广播计算 input_mask_expanded attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float() sum_embeddings torch.sum(last_hidden_state * input_mask_expanded, 1) sum_mask torch.clamp(input_mask_expanded.sum(1), min1e-9) embedding sum_embeddings / sum_mask # 将向量转换为Python列表并做归一化余弦相似度通常需要归一化向量 embedding embedding.cpu().numpy()[0] embedding embedding / (embedding**2).sum()**0.5 # L2归一化 return embedding.tolist() # 返回384维的列表 except Exception as e: print(f处理文本时出错{text[:50]}...错误{e}) return None # 2. 连接MySQL数据库 def connect_db(): try: connection pymysql.connect( hostlocalhost, # 你的数据库地址 useryour_username, # 你的数据库用户名 passwordyour_password, # 你的数据库密码 databaseyour_database_name, # 你的数据库名 charsetutf8mb4 ) print(数据库连接成功) return connection except pymysql.Error as e: print(f数据库连接失败{e}) sys.exit(1) # 3. 主函数读取文章生成向量更新数据库 def main(): conn connect_db() cursor conn.cursor() # 首先找出所有 title_vector 为空的记录 select_sql SELECT id, title FROM knowledge_articles WHERE title_vector IS NULL cursor.execute(select_sql) articles cursor.fetchall() print(f找到 {len(articles)} 条待处理文章。) update_count 0 for article_id, title in articles: print(f正在处理文章ID {article_id}: {title[:30]}...) # 生成标题向量 vector get_embedding(title) if vector: # 将向量列表转换为JSON字符串 vector_json json.dumps(vector) # 更新数据库 update_sql UPDATE knowledge_articles SET title_vector %s WHERE id %s cursor.execute(update_sql, (vector_json, article_id)) update_count 1 else: print(f 文章ID {article_id} 向量生成失败跳过。) # 提交事务并关闭连接 conn.commit() cursor.close() conn.close() print(f处理完成成功更新了 {update_count} 篇文章的向量。) if __name__ __main__: main()脚本工作流程解析加载模型从Hugging Face下载或读取本地的GTE-Base-ZH模型。定义向量化函数get_embedding函数接收一段文本通过模型计算出其向量表示。里面的池化Pooling和归一化Normalization操作是为了得到一个稳定、标准的句子向量这对后续计算余弦相似度很重要。连接数据库读取那些还没有向量的文章标题。批量处理循环处理每篇文章生成向量并更新回数据库的title_vector字段。运行这个脚本你的数据库里的文章就都拥有自己的“语义身份证”了。这是整个项目最核心的数据预处理步骤。4. 第三步实现语义相似度检索SQL查询向量都存好了怎么用呢关键就在于如何用SQL计算余弦相似度。余弦相似度的公式虽然涉及点积和模长但因为我们存储的是已经归一化后的向量上一步脚本里做了公式就简化成了两个向量的点积。假设用户输入的查询句子是“编程学习的方法”。我们需要用同样的Python脚本可以单独写个函数把这个查询句变成向量query_vec。在SQL中计算query_vec与数据库中每一条title_vector的点积。下面是一个示例的SQL查询语句-- 假设我们已经得到了查询向量这里用一个示例向量代替 SET query_vector JSON_ARRAY(0.02, -0.1, 0.08, ... , 0.05); -- 这里应是384个数值 SELECT id, title, content, -- 计算余弦相似度对两个JSON数组进行点积运算 ( SELECT SUM(JSON_EXTRACT(query_vector, CONCAT($[, idx, ])) * JSON_EXTRACT(title_vector, CONCAT($[, idx, ]))) FROM (SELECT 0 AS idx UNION SELECT 1 UNION SELECT 2 ... UNION SELECT 383) AS indices ) AS similarity_score FROM knowledge_articles WHERE title_vector IS NOT NULL ORDER BY similarity_score DESC LIMIT 10;但是上面的SQL有个问题我们需要动态生成0到383的索引序列并且计算效率不高。在MySQL 8.0中我们可以利用JSON_TABLE函数和INNER JOIN更优雅、更高效地完成这个计算。下面是一个改进版更适合在应用程序中拼接执行的查询示例# 在Python中假设我们已经得到了查询向量 query_vec_list (一个Python list) import json query_vec_json json.dumps(query_vec_list) # 转换为JSON字符串 # 构造SQL使用JSON_TABLE展开向量并计算点积MySQL 8.0 sql f SELECT a.id, a.title, a.content, SUM(q.value * t.value) AS similarity_score FROM knowledge_articles a CROSS JOIN JSON_TABLE(%s, $[*] COLUMNS(idx FOR ORDINALITY, value DOUBLE PATH $)) AS q CROSS JOIN JSON_TABLE(a.title_vector, $[*] COLUMNS(idx FOR ORDINALITY, value DOUBLE PATH $)) AS t WHERE q.idx t.idx AND a.title_vector IS NOT NULL GROUP BY a.id, a.title, a.content ORDER BY similarity_score DESC LIMIT 10; cursor.execute(sql, (query_vec_json,)) results cursor.fetchall()这个查询做了以下几件事JSON_TABLE将查询向量和数据库中的每个标题向量“展开”成一行行的数字带索引。通过q.idx t.idx确保按位置对齐。SUM(q.value * t.value)就是对位的数值相乘后求和即点积运算也就是余弦相似度。最后按相似度降序排列取出最相似的10条结果。5. 第四步构建完整的课程设计应用把前面三步串起来我们就得到了一个完整的、可演示的课程设计项目。你可以创建一个简单的Flask或FastAPI应用提供一个搜索接口。这里给出一个极简的Flask应用示例app.pyfrom flask import Flask, request, jsonify import pymysql import json from generate_embeddings import get_embedding # 导入之前写的向量生成函数 app Flask(__name__) # 数据库配置应放入配置文件中 DB_CONFIG { host: localhost, user: your_username, password: your_password, database: your_database_name, charset: utf8mb4 } def search_similar_articles(query_text, top_k10): 语义搜索主函数 # 1. 将查询文本转换为向量 query_vector get_embedding(query_text) if not query_vector: return [] query_vec_json json.dumps(query_vector) # 2. 连接数据库并执行相似度查询 conn pymysql.connect(**DB_CONFIG) cursor conn.cursor(pymysql.cursors.DictCursor) sql SELECT a.id, a.title, a.content, SUM(q.value * t.value) AS similarity_score FROM knowledge_articles a CROSS JOIN JSON_TABLE(%s, $[*] COLUMNS(idx FOR ORDINALITY, value DOUBLE PATH $)) AS q CROSS JOIN JSON_TABLE(a.title_vector, $[*] COLUMNS(idx FOR ORDINALITY, value DOUBLE PATH $)) AS t WHERE q.idx t.idx AND a.title_vector IS NOT NULL GROUP BY a.id, a.title, a.content ORDER BY similarity_score DESC LIMIT %s; cursor.execute(sql, (query_vec_json, top_k)) results cursor.fetchall() cursor.close() conn.close() return results app.route(/search, methods[GET]) def search(): 搜索API接口 query request.args.get(q, ) if not query: return jsonify({error: 请输入查询内容}), 400 try: top_k int(request.args.get(top_k, 10)) articles search_similar_articles(query, top_k) return jsonify({query: query, results: articles}) except Exception as e: return jsonify({error: str(e)}), 500 if __name__ __main__: app.run(debugTrue, port5000)运行这个应用后你可以在浏览器访问http://localhost:5000/search?q编程入门就能看到返回的语义相似的搜索结果了。这比单纯的关键字匹配“编程”和“入门”能找到更相关、更丰富的内容。6. 总结与课程设计报告建议走完整个流程你会发现给数据库加上语义检索能力并没有想象中那么神秘。核心就是向量化、存储和相似度计算这三步。这个项目完美地将数据库原理、Python编程和AI模型应用结合在了一起。在做课程设计报告时你可以围绕以下几个部分展开项目背景与意义阐述传统关键词检索的局限引入语义检索的必要性和优势。系统设计画出系统架构图数据流用户输入 - 向量化 - 数据库查询 - 结果返回详细说明数据库表结构设计特别是JSON类型字段的选择原因。核心实现这是报告的重点。分模块讲解向量生成模块Python脚本的流程、关键函数。数据预处理流程如何将存量数据向量化。语义检索SQL查询详细解释余弦相似度在MySQL中的计算实现对比简化公式与完整公式。实验与结果分析设计测试用例。例如查询“学习编程”是否能返回“Python入门”、“代码教学”等内容与LIKE关键字搜索进行对比展示语义搜索在查全率上的优势。可以做一个简单的对比表格展示不同查询词下两种方式的返回结果差异。总结与展望总结项目的收获分析当前方案的优缺点如MySQL全表计算效率问题并提出可能的优化方向例如引入向量索引、使用专用向量数据库、尝试更先进的模型等。这个项目最出彩的地方在于它不仅仅是一个理论设计而是一个可以实际运行、看到效果的完整系统。它展示了如何将前沿的AI能力与传统数据库技术相结合解决实际问题。无论是用于答辩还是写入简历都是一个非常有说服力的实践项目。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。