简介中华成语数据库面向汉语学习者、语文教师、文化研究者及数据开发人员提供一套结构完整的成语语料资源可用于成语检索、教学备课、语言统计分析与文化溯源等场景。压缩包共3个文件约6.63MB包含csv、sql与txt三种格式csv便于表格软件直接查看与筛选sql可直接导入关系数据库建表查询txt则方便非技术用户阅读或二次处理。数据覆盖31851个成语每条均含拼音与释义多数还附有出处和例句字段设计兼顾查询与统计需求。已有1066人学习下载说明其在成语学习与数据处理场景中具备一定参考价值。借助该库读者可快速搭建成语查询系统、按出处或关键字做统计分析也能为教学课件、文化科普内容提供可靠素材是深入了解与利用汉语成语的实用工具。1. 三万条成语灌进数据库这份 CSVSQLTXT 三件套到底能干什么做中文 NLP 的同行大概都遇到过这个场景想给模型加一点成语相关的语料或者做一个成语接龙、成语释义查询的小工具结果发现网上能找到的成语数据要么只有几百条要么字段残缺拼音和出处对不上号。我最近拆了一个叫「中华成语数据库」的资源包里面一共 31851 条成语每条都带拼音和解释大多数还附了出处和例句压缩包里给了cysj.csv、CYSJ.txt、cysj.sql三种格式。这个量级基本覆盖了日常能碰到的全部成语字段结构也够用。适合做数据入库、语料清洗、词典类应用开发或者单纯想拿 SQL 练手的人。下面我按实际拆包和入库的流程把这份资源怎么用、参数怎么调、哪里容易翻车讲清楚。2. 三种格式怎么选CSV、SQL、TXT 的适用边界与字段结构拿到压缩包先别急着全部导入三种格式对应的是三种不同的使用路径。选错了格式后面要么多写一堆转换脚本要么导入到一半发现字段对不上。这一章先把三种格式的定位和字段结构拆开讲再给出各自的落地方式。2.1 CSV 格式字段解析与编码确认cysj.csv是通用性最好的格式Excel、Python、数据库工具都能直接读。但 CSV 有个经典问题中文编码。这份资源大概率是 UTF-8 或 GBK导入前必须先确认否则会出现乱码。先用 Python 快速探一下编码和字段结构import csv import chardet # 先探测文件编码避免直接读取出现乱码 with open(cysj.csv, rb) as f: raw f.read(10000) result chardet.detect(raw) print(f检测编码: {result[encoding]}, 置信度: {result[confidence]}) # 用检测到的编码读取前 5 行确认字段结构 with open(cysj.csv, r, encodingresult[encoding]) as f: reader csv.reader(f) for i, row in enumerate(reader): if i 5: break print(f第{i1}行 字段数{len(row)}: {row})这段代码先读前 10000 字节做编码探测再用探测结果打开文件。chardet.detect返回的confidence低于 0.7 时建议手动试 UTF-8 和 GBK 两种。字段数如果每行不一致说明 CSV 里有未转义的逗号需要检查解释或例句字段是否被引号包裹。常见做法是确认编码后用 pandas 直接读指定encoding和on_bad_linesskip先把脏行跳过再单独排查。import pandas as pd # 读取 CSV跳过字段数异常的行 df pd.read_csv(cysj.csv, encodingutf-8, on_bad_linesskip) print(df.columns.tolist()) # 查看列名 print(df.shape) # 确认行数是否接近 31851 print(df.head(3)) # 预览前 3 行on_bad_linesskip会丢弃解析失败的行导入后要对比df.shape[0]和 31851 的差值差太多说明 CSV 本身有结构问题。列名如果是英文如 id、idiom、pinyin、explanation、source、example后续入库时映射成中文列名即可。2.2 SQL 格式直接执行脚本建库建表cysj.sql是给关系数据库用的里面通常包含CREATE TABLE和批量INSERT。我一般用 MySQL 或 SQLite 跑SQLite 最省事不用装服务。# 用 SQLite 直接执行 SQL 脚本生成数据库文件 sqlite3 chengyu.db cysj.sql # 进入交互模式验证 sqlite3 chengyu.db SELECT COUNT(*) FROM chengyu; sqlite3 chengyu.db SELECT * FROM chengyu LIMIT 3;如果表名不是chengyu先执行.tables查看实际表名。SQL 脚本里如果有CREATE DATABASE或USE语句SQLite 会报错需要手动删掉那几行再执行。MySQL 的话先建库再导入CREATE DATABASE chengyu_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE chengyu_db; SOURCE /path/to/cysj.sql;utf8mb4是必须的成语里可能有生僻字utf8三字节存不下。导入后执行SELECT COUNT(*)确认行数再检查SHOW CREATE TABLE看字段类型是否合理比如解释字段是不是TEXT而不是VARCHAR(255)。2.3 TXT 格式纯文本的快速检索与预处理CYSJ.txt适合做快速全文检索或者喂给文本处理工具。纯文本没有结构通常是一行一条成语字段之间用空格、制表符或特定分隔符隔开。先看前几行确认分隔方式# 查看文件前 10 行确认分隔符和字段顺序 head -n 10 CYSJ.txt # 统计总行数和 31851 对比 wc -l CYSJ.txt如果字段之间是制表符可以用awk快速提取某一列# 假设第 2 列是成语提取所有成语并去重 awk -F\t {print $2} CYSJ.txt | sort -u | wc -lTXT 的最大价值是轻量不用起数据库就能做 grep 检索。比如想找所有包含「龙」字的成语grep 龙 CYSJ.txt | head -n 20但 TXT 不适合做结构化查询比如「找出处为《论语》且拼音以 y 开头的成语」这种还是得走 SQL。2.4 三种格式的选型对照格式适用场景导入难度结构化程度推荐工具CSV数据分析、Excel 查看、批量导入低中pandas、Navicat、DBeaverSQL直接建库、复杂查询、应用后端中高MySQL、SQLite、SQL ServerTXT快速检索、文本预处理、轻量脚本低低grep、awk、Python 文件读写选型逻辑很简单要做查询和关联分析走 SQL要做数据清洗和转换走 CSV只想快速搜几个成语TXT 够了。三个格式的数据应该是一致的导入后可以交叉验证行数和关键字段。3. 入库实操从 CSV 到 MySQL 的完整流程与字段映射选好格式之后真正落地到数据库才是重头戏。这一章以 CSV 导入 MySQL 为主线把建表、字段映射、批量插入、索引优化串起来。SQL 脚本直接执行的方式在 2.2 已经讲过这里补 CSV 路径的完整操作。3.1 建表语句与字段类型选择先根据 CSV 的列结构建一张表。假设 CSV 列依次是ID、成语、拼音、解释、出处、例句。建表时字段类型要按实际内容长度选别一股脑用VARCHAR(255)。CREATE TABLE chengyu ( id INT PRIMARY KEY AUTO_INCREMENT, idiom VARCHAR(20) NOT NULL COMMENT 成语文本, pinyin VARCHAR(100) DEFAULT NULL COMMENT 拼音, explanation TEXT COMMENT 解释, source VARCHAR(200) DEFAULT NULL COMMENT 出处, example TEXT COMMENT 例句, INDEX idx_idiom (idiom), INDEX idx_pinyin (pinyin) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;idiom用VARCHAR(20)足够最长的成语也就十几个字。pinyin给 100 字符因为带声调的拼音可能较长。explanation和example用TEXT解释和例句长度不可控。索引加在idiom和pinyin上因为这两个字段最常用来查询。utf8mb4和utf8mb4_unicode_ci保证生僻字和排序正确。3.2 用 Python 做字段映射与批量插入CSV 的列名可能是英文也可能没有表头需要先确认再映射。下面这段脚本做了四件事读 CSV、重命名列、清洗空值、批量插入。import pandas as pd from sqlalchemy import create_engine # 读取 CSV假设无表头手动指定列名 df pd.read_csv(cysj.csv, encodingutf-8, headerNone, names[id, idiom, pinyin, explanation, source, example], on_bad_linesskip) # 清洗去掉成语为空的行解释为空填占位符 df df.dropna(subset[idiom]) df[explanation] df[explanation].fillna(暂无解释) df[source] df[source].fillna() df[example] df[example].fillna() # 建立数据库连接charset 必须指定 utf8mb4 engine create_engine( mysqlpymysql://root:passwordlocalhost:3306/chengyu_db?charsetutf8mb4 ) # 批量插入chunksize 控制每次写入行数 df.to_sql(chengyu, conengine, if_existsappend, indexFalse, chunksize1000, methodmulti) print(f导入完成共 {len(df)} 条)headerNone是因为不确定 CSV 有没有表头如果有就改成header0并调整names。on_bad_linesskip跳过解析异常的行。chunksize1000是每次批量插入的行数太大容易超时太小效率低1000 到 5000 之间比较稳。methodmulti让 pandas 拼多值 INSERT比逐条插入快一个数量级。连接串里的charsetutf8mb4不能省否则生僻字会变成问号。导入后验证SELECT COUNT(*) FROM chengyu; SELECT * FROM chengyu WHERE idiom 画蛇添足; SELECT COUNT(*) FROM chengyu WHERE source LIKE %论语%;第一条确认总数是否接近 31851第二条验证单条数据完整性第三条测试出处检索。如果总数差很多回到 CSV 检查on_bad_lines跳过了多少行。3.3 索引与查询性能调优数据量三万多条不算大但没有索引的LIKE %关键词%查询依然会全表扫描。除了 3.1 建的两个索引如果经常按出处查可以再加一个ALTER TABLE chengyu ADD INDEX idx_source (source(50));source(50)是前缀索引因为出处字段可能较长全文索引没必要。查询时尽量用等值或前缀匹配-- 走索引快 SELECT * FROM chengyu WHERE idiom LIKE 一%; -- 不走索引全表扫描三万多条还能接受 SELECT * FROM chengyu WHERE explanation LIKE %比喻%;如果要做全文检索MySQL 的FULLTEXT索引对中文支持一般常见做法是交给 Elasticsearch 或者用LIKE凑合。三万多条的数据量LIKE全表扫描在毫秒级不用过度优化。3.4 用 SQL 做成语统计分析入库之后SQL 的价值就体现出来了。比如统计每个出处贡献了多少成语SELECT source, COUNT(*) AS cnt FROM chengyu WHERE source ! GROUP BY source ORDER BY cnt DESC LIMIT 20;找出拼音以某个字母开头的成语数量分布SELECT LEFT(pinyin, 1) AS initial, COUNT(*) AS cnt FROM chengyu WHERE pinyin IS NOT NULL GROUP BY initial ORDER BY cnt DESC;这些查询在 CSV 里用 pandas 也能做但 SQL 写起来更直观而且方便对接后端应用。如果要做成语接龙可以用idiom LIKE CONCAT(%, ?, %)或者更精确的尾字匹配不过尾字匹配需要额外提取最后一个字建索引这是进阶用法最后一章会提。4. 避坑与排查编码、字段截断、导入中断的常见问题这一章记录我在导入和使用过程中实际踩过的坑每条按「现象 → 原因 → 解决」写。三万多条数据看着不多但中文数据的坑一个不少。4.1 导入后中文变问号或乱码现象CSV 导入 MySQL 后成语和解释显示为???或乱码。原因连接字符集不是utf8mb4或者 CSV 文件本身是 GBK 编码但按 UTF-8 读取。解决先确认 CSV 编码用 2.1 的 chardet 脚本读取时指定正确编码。数据库连接串加?charsetutf8mb4建表时指定DEFAULT CHARSETutf8mb4。MySQL 服务端的character_set_server也建议设为utf8mb4改完重启生效。4.2 字段被截断解释只剩前半句现象导入后explanation字段内容不完整末尾被切掉。原因建表时解释字段用了VARCHAR(255)但部分成语解释超过 255 字符。解决把explanation和example改成TEXT类型。如果已经建表执行ALTER TABLE chengyu MODIFY explanation TEXT;。导入前先用 pandas 统计各字段最大长度df[explanation].str.len().max()按实际长度选类型。4.3 批量插入中途报错部分数据丢失现象to_sql执行到一半报OperationalError数据库里只有部分数据。原因单次批量太大导致超时或者某行数据包含特殊字符如反斜杠、引号导致 SQL 语法错误。解决把chunksize调小到 500 或 1000分批次插入。特殊字符问题用参数化插入pandas 的to_sql默认会处理转义但如果用methodmulti拼 SQL某些字符仍可能出问题。稳妥做法是先用df.to_sql不带method参数试一次确认数据干净后再换multi提速。4.4 SQL 脚本在 SQLite 里执行报语法错误现象sqlite3 chengyu.db cysj.sql报near CREATE: syntax error或near USE: syntax error。原因cysj.sql是为 MySQL 写的包含CREATE DATABASE、USE、ENGINEInnoDB等 SQLite 不支持的语法。解决用文本编辑器打开cysj.sql删掉CREATE DATABASE、USE、ENGINEInnoDB、DEFAULT CHARSET等 MySQL 特有语句只保留CREATE TABLE和INSERT。或者直接用 MySQL 导入别用 SQLite。4.5 CSV 行数和数据库行数对不上现象CSV 有 31851 行导入后SELECT COUNT(*)只有三万一出头。原因on_bad_linesskip跳过了字段数异常的行或者 CSV 里有空行、重复行。解决先用wc -l cysj.csv看原始行数再用 pandas 读的时候不加on_bad_lines看报错行号定位具体问题。重复行用df.drop_duplicates(subset[idiom])去重。如果 CSV 本身有表头wc -l会比实际数据多一行注意减掉。5. 进阶用法成语接龙查询与拼音首字母检索的 SQL 技巧数据入库只是第一步真正让这份资源发挥价值的是在上面做查询和应用。这一章讲两个具体技巧成语接龙查询和拼音首字母检索。都是我在做小工具时实际用到的SQL 直接能跑。5.1 成语接龙尾字匹配与递归查询成语接龙的核心是「上一条的最后一个字 下一条的第一个字」。但数据库里存的是完整成语没有单独存首字和尾字。有两个做法一是查询时用SUBSTRING实时截取二是加两个生成列。实时截取的方式-- 找出以「足」字开头的成语接「画蛇添足」 SELECT idiom, pinyin, explanation FROM chengyu WHERE idiom LIKE 足% LIMIT 10;LIKE 足%走idx_idiom索引速度很快。但尾字匹配需要SUBSTRING(idiom, -1)这个不走索引-- 找出所有尾字为「足」的成语 SELECT idiom FROM chengyu WHERE SUBSTRING(idiom, -1) 足;三万多条全表扫描也就几十毫秒可以接受。如果要频繁做接龙建议加两个生成列并建索引ALTER TABLE chengyu ADD COLUMN first_char VARCHAR(1) GENERATED ALWAYS AS (LEFT(idiom, 1)) STORED, ADD COLUMN last_char VARCHAR(1) GENERATED ALWAYS AS (RIGHT(idiom, 1)) STORED, ADD INDEX idx_first (first_char), ADD INDEX idx_last (last_char);MySQL 5.7 以上支持生成列。加完之后接龙查询变成-- 接「画蛇添足」找首字为「足」的成语 SELECT idiom FROM chengyu WHERE first_char 足; -- 找所有能接在「足」后面的成语 SELECT idiom FROM chengyu WHERE first_char 足 AND last_char ! 足;生成列的好处是索引直接生效查询从全表扫描变成索引查找。注意RIGHT(idiom, 1)对多字节字符也有效MySQL 的RIGHT按字符截取不是按字节。5.2 拼音首字母检索从拼音字段提取声母很多成语查询工具支持按拼音首字母搜比如输入hst找「画蛇添足」。这需要从拼音字段提取每个字的声母。拼音字段格式通常是hua she tian zu或huà shé tiān zú带空格分隔。提取首字母的 SQL-- 假设拼音格式为 hua she tian zu提取首字母 SELECT idiom, pinyin, UPPER(CONCAT( LEFT(SUBSTRING_INDEX(pinyin, , 1), 1), LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(pinyin, , 2), , -1), 1), LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(pinyin, , 3), , -1), 1), LEFT(SUBSTRING_INDEX(pinyin, , -1), 1) )) AS initials FROM chengyu WHERE pinyin LIKE % % % % LIMIT 10;这段 SQL 用SUBSTRING_INDEX按空格拆分拼音取每个音节的首字母再拼接。只处理四字成语拼音有四个音节其他长度的成语需要调整。如果拼音带声调符号LEFT取到的可能是带声调的字母需要额外映射常见做法是在应用层用 Python 处理而不是在 SQL 里硬做。Python 处理更灵活def get_initials(pinyin): 从拼音字符串提取首字母如 hua she tian zu - HSTZ if not pinyin: return parts pinyin.split() return .join(p[0].upper() for p in parts if p) # 在 pandas 里批量生成 df[initials] df[pinyin].apply(get_initials)生成后可以把initials写回数据库加索引查询时直接WHERE initials HSTZ。这个字段对做搜索建议特别有用。5.3 验证数据完整性的几个查询导入完成后用几个查询快速验证数据质量-- 检查拼音为空的成语数量 SELECT COUNT(*) FROM chengyu WHERE pinyin IS NULL OR pinyin ; -- 检查解释为空的成语数量 SELECT COUNT(*) FROM chengyu WHERE explanation IS NULL OR explanation ; -- 检查出处非空的成语占比 SELECT COUNT(*) AS total, SUM(CASE WHEN source ! THEN 1 ELSE 0 END) AS has_source, ROUND(SUM(CASE WHEN source ! THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS pct FROM chengyu; -- 检查重复成语 SELECT idiom, COUNT(*) AS cnt FROM chengyu GROUP BY idiom HAVING cnt 1;这几个查询能快速告诉你数据完整度。如果拼音缺失比例高可能是 CSV 解析时某些行字段错位如果重复成语多需要去重。我一般会在导入后跑一遍这些检查确认没问题再开始做上层应用。从那以后我每次拿到这种多格式的数据包都先把三种格式各抽十条对比字段一致性再跑一遍完整性查询最后才入库。这个习惯帮我省了不少返工的时间。希望帮到你。本文还有配套的精品资源点击获取