news 2026/10/13 1:02:11

全国五级行政区划数据导入MySQL:表结构设计与批量导入实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
全国五级行政区划数据导入MySQL:表结构设计与批量导入实战

简介:这份资源面向从事地理信息、数据开发、政务信息化及统计分析的技术人员,提供一套覆盖全国行政区划层级的结构化数据集合,可用于地址库搭建、区域级联选择、数据可视化与业务系统底表建设。压缩包共4个文件,包含sql数据库脚本、xls表格、说明文档与示意图,整体约13.9MB,其中sql文件可直接导入MySQL生成省、市、县、镇、村多级数据表,xls表格则便于在Excel中快速查阅与二次加工,说明文档对字段含义与使用方式做了必要交代。目前已有1452人学习下载,说明该数据在同类资源中具备一定参考价值。数据按行政区划代码组织,层级关系清晰,适合用于下拉联动、区域统计、地址解析等场景,也可作为数据清洗与校验的基础底表,帮助读者省去逐级采集与整理的时间成本。

1. 全国五级行政区划数据落库:一份 rar 包到底能解决什么问题

拿到「最新全国各省、市、县、镇、村 mysql 数据库 + excel 表格数据.rar」这类资源,第一反应往往是先解压看看里面有什么,然后就开始纠结:Excel 直接打开够不够用,为什么还要折腾 MySQL?我做过好几个跟行政区划数据打交道的项目,从门店地址补全、物流分区计价,到用户注册时的四级联动下拉框,结论很一致——Excel 适合看,MySQL 适合用。五级区划数据(省、市、县、镇、村)全国量级在几十万到上百万行,Excel 打开慢、筛选卡、多表关联基本靠 VLOOKUP 硬撑,一旦要做「按村统计」「按镇聚合」「模糊匹配地址」这类操作,Excel 就会变成体力活。而 MySQL 建好索引之后,同样的查询是毫秒级的事。这篇笔记就围绕这份 rar 包,讲清楚怎么把里面的 Excel 数据规整地导入 MySQL、表结构怎么设计、导入过程有哪些坑、以及导入之后能拿它做什么。适合手里已经有类似数据、准备做地址库或区划联动的后端和数据分析同学,也适合还在用 Excel 硬扛的运营开发。

2. 从 rar 到 MySQL:五级区划数据的表结构设计与导入路径

2.1 先看清 rar 包里通常有什么,再决定拆几张表

这类资源包解压后,常见的内容是若干 Excel 文件,按层级拆分,比如省级一张、市级一张、区县一张、乡镇一张、村居一张,也可能是一张宽表把所有层级拼在一起。两种形态处理方式完全不同。分层的多文件结构更适合拆成多张表,用行政代码做外键关联;一张宽表则更适合先导入再做拆分。我一般会先解压后列一下文件清单,确认每个文件有哪些列,重点看有没有这几列:省级代码、省级名称、市级代码、市级名称、区县代码、区县名称、乡镇代码、乡镇名称、村居代码、村居名称,以及可能的城乡分类代码、经纬度、拼音首字母。行政代码是这套数据的骨架,国家标准是 6 位到村一级(村级是 12 位),前 2 位省、前 4 位市、前 6 位县、前 9 位镇、前 12 位村,这个前缀规则决定了后面能不能靠代码直接做层级过滤,而不必层层 JOIN。

表结构设计上,我推荐两种方案二选一。方案 A 是单表宽表,把所有层级塞进一张region表,字段包括code、name、level、parent_code,level 用 1 到 5 表示省到村。方案 B 是分层多表,province、city、county、town、village各一张,靠 code 前缀关联。方案 A 查询简单,一次 WHERE level=3 就能拿所有区县,缺点是单表行数大、维护时容易误改;方案 B 结构清晰、每张表职责单一,缺点是做跨级查询要 JOIN。我实际项目里更偏向方案 A,因为区划数据基本是只读的,查询便利性比写入规范更重要。下面给出方案 A 的建表语句,字段类型和索引都按实际查询习惯来定。

-- 行政区划单表结构,level: 1省 2市 3县 4镇 5村 CREATE TABLE `region` ( `code` VARCHAR(12) NOT NULL COMMENT '行政区划代码,村级12位', `name` VARCHAR(100) NOT NULL COMMENT '区划名称', `level` TINYINT NOT NULL COMMENT '层级 1-5', `parent_code` VARCHAR(12) NOT NULL DEFAULT '' COMMENT '上级区划代码', `pinyin` VARCHAR(100) DEFAULT NULL COMMENT '拼音首字母,可选', `lng` DECIMAL(10,6) DEFAULT NULL COMMENT '经度,可选', `lat` DECIMAL(10,6) DEFAULT NULL COMMENT '纬度,可选', PRIMARY KEY (`code`), KEY `idx_parent` (`parent_code`), KEY `idx_level_name` (`level`, `name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

这段建表语句里几个点值得说清楚。code用 VARCHAR 而不是 INT,因为村级代码是 12 位,虽然没超 INT 范围,但行政区划代码是标识符不是数值,用字符串能避免前导零丢失和排序歧义。parent_code建了普通索引,因为「查某个市下面所有区县」是最常见的查询。idx_level_name复合索引服务于「按层级 + 名称模糊查」的场景,比如用户输入「朝阳」想匹配所有叫朝阳的区县。字符集用 utf8mb4,因为区划名称里偶尔会有生僻字,utf8 三字节版本会丢字。lng/lat用 DECIMAL 而不是 FLOAT,避免精度漂移,虽然区划数据里经纬度不是必须的,但如果有就顺手存上,后面做地图打点省事。

2.2 用 Python 把 Excel 读进来再批量写 MySQL,比直接导入稳

Excel 导入 MySQL 有两条路:一条是用 Navicat、DBeaver 这类工具的导入向导,另一条是自己写脚本。工具导入适合一次性、数据干净的情况,但区划数据往往有合并单元格、表头多行、代码列被识别成科学计数法这些问题,工具导入翻车概率不低。我一般用 Python 的 pandas + pymysql 组合,读进来先清洗再批量插入,可控性高很多。下面这段脚本处理的是分层多文件的情况,读五个 Excel,统一成 region 表的格式,再批量写入。

import pandas as pd import pymysql # 数据库连接,按自己环境改 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='your_password', database='region_db', charset='utf8mb4' ) cursor = conn.cursor() # 文件与层级映射,文件名按实际解压结果改 files = { 'province.xlsx': 1, 'city.xlsx': 2, 'county.xlsx': 3, 'town.xlsx': 4, 'village.xlsx': 5, } rows = [] for fname, level in files.items(): # dtype=str 关键,防止代码列被读成数字丢前导零 df = pd.read_excel(fname, dtype=str) df = df.fillna('') # 空值统一成空串 for _, r in df.iterrows(): code = str(r['code']).strip() name = str(r['name']).strip() if not code or not name: continue # 跳过空行 parent = code[:-2] if level > 1 else '' # 按前缀截取上级代码 rows.append((code, name, level, parent)) # 批量插入,executemany 比逐条 insert 快一个数量级 sql = "INSERT INTO region (code, name, level, parent_code) VALUES (%s, %s, %s, %s)" cursor.executemany(sql, rows) conn.commit() print(f"共写入 {len(rows)} 条") cursor.close() conn.close()

这段脚本有几个参数和写法是踩过坑之后固定下来的。dtype=str必须加,否则 pandas 会把 110000 这种代码读成整数,村级 12 位代码还可能被读成科学计数法,前导零直接没了。fillna('')是为了让空单元格变成空串,避免 NaN 混进 SQL 变成字符串 'nan'。parent_code用code[:-2]截取,前提是代码严格按 2 位一级递增,如果数据里代码位数不齐,这一步会出错,所以导入前最好先df['code'].str.len().value_counts()看一眼长度分布。executemany是批量提交,比循环单条 insert 快很多,几十万行数据几分钟能跑完。如果数据量特别大,可以再按 5000 条一批分次 commit,避免单次事务过大。

2.3 导入后的校验:三张表对不上就是数据有问题

导入完成不等于数据可用,必须做校验。我一般跑三类检查。第一类是行数校验,每个层级的行数应该和官方公布的区划数量大致对得上,省级 30 多个、市级 300 多个、区县 2800 多个、乡镇 4 万左右、村居 60 万上下,数量级差太多说明有文件没读全或读重了。第二类是父子完整性校验,每个非省级记录的 parent_code 都应该能在表里找到对应记录,找不到就是孤儿节点。第三类是代码长度校验,每个层级的代码长度应该一致。下面这条 SQL 查孤儿节点,跑出来有结果就说明数据有问题。

-- 查孤儿节点:parent_code 在表里找不到对应 code SELECT r.code, r.name, r.level, r.parent_code FROM region r LEFT JOIN region p ON r.parent_code = p.code WHERE r.level > 1 AND p.code IS NULL LIMIT 50;

如果这条 SQL 返回了记录,先别急着改数据,去看原始 Excel 里这些记录的上级代码是不是写错了,或者上级那一层文件是不是漏了。区划数据最常见的坑就是某一年做了区划调整,上级代码变了但下级没同步,导致对不上。校验通过之后,建议给 region 表加一个覆盖索引或者物化一张「省市区」三级视图,因为大部分业务只需要到区县一级,村级数据平时用不到,单独查三级会快很多。

3. Excel 和 MySQL 怎么配合:加载项被禁用、批量出图、统计求和这些场景

3.1 Excel 加载项被禁用时,用 Python 直接读写反而更省事

很多人拿到 rar 包第一件事是双击 Excel 打开,结果遇到「Excel 加载项被禁用」的提示,或者 Ctrl+V 失效、Ctrl 键用不了,这些在热词里出现频率很高。这类问题多半是 Excel 的 COM 加载项冲突或者剪贴板被其他程序占用,跟数据本身没关系。我的建议是,如果只是要看数据,用 WPS 或者 LibreOffice 打开往往能绕过;如果是要处理数据,干脆别在 Excel 里折腾,直接用 Python 的 openpyxl 或 pandas 读写。比如要把 MySQL 里的区划数据导回 Excel 给运营用,用 pandas 一行就能写出去。

import pandas as pd import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='your_password', database='region_db', charset='utf8mb4') # 只导区县一级,村级数据太大 Excel 扛不住 df = pd.read_sql("SELECT code, name, parent_code FROM region WHERE level=3", conn) df.to_excel('county.xlsx', index=False, engine='openpyxl') conn.close()

to_excel指定engine='openpyxl'是为了支持 xlsx 格式,如果数据超过 100 万行,Excel 单表上限是 104 万行,村级数据可能超,这时候要么分 sheet 写,要么直接给 CSV。index=False避免多出一列索引。这种「MySQL 存全量、Excel 出切片」的模式,比在 Excel 里维护全量数据靠谱得多,也避开了加载项被禁用这类玄学问题。

3.2 用 SQL 做「同一列含关键词求和」比 Excel 函数快得多

热词里有个很典型的诉求:Excel 同一列中统计含关键词对应数据求和。在 Excel 里这要写 SUMIF 加通配符,数据一多就卡。放到 MySQL 里就是一句 LIKE 加 SUM。假设有一张订单表,要统计收货地址里含「朝阳」的订单金额总和,SQL 是这样。

-- 统计地址含关键词的金额总和,region 表辅助确认区划 SELECT SUM(o.amount) AS total FROM orders o WHERE o.address LIKE '%朝阳%';

如果要做更精确的匹配,比如只统计北京市朝阳区的订单,那就用区划代码关联,而不是靠名称模糊匹配,因为全国叫「朝阳」的区不止一个。这也是为什么区划数据要落库——有了 code,地址匹配可以从「字符串包含」升级成「代码精确关联」,准确率和性能都上一个台阶。实际项目里我会先把用户地址做一次区划解析,把解析出的 code 存到订单表,后续统计直接按 code 聚合,不再每次跑 LIKE。

3.3 区划数据导入 ArcGIS 批量出图:Excel 转表再关联

热词里还有「arcgis 批量出图想插入 excel 表格」「excel 表格怎么导入 arcgis10.8」,这跟区划数据是天然搭配。ArcGIS 导入 Excel 的常见问题是字段类型识别错误,尤其是代码列。稳妥做法是先把 Excel 另存为 CSV,再用 ArcGIS 的「Excel 转表」或「表转表」工具导入,导入后手动把代码字段设成文本型。如果区划数据里带了经纬度,可以直接用「显示 XY 数据」生成点图层;如果没有经纬度,就需要一份带边界的区划矢量数据,用 code 字段做连接(Join)。连接字段两边都必须是文本型,一边是数字一边是文本是连不上的,这是最常见的翻车点。批量出图的话,用 ArcGIS 的 Data Driven Pages(现在叫 Map Series)按区划代码分页,比手动一张张出图省事得多。

4. 导入和查询区划数据时最容易翻车的五个地方

4.1 代码列变成科学计数法或丢前导零

现象:Excel 里明明是 110000,导入 MySQL 后变成 110000 没问题,但村级 110101001001 这种 12 位代码在 Excel 里显示成 1.10101E+11,导入后变成 110101001001 但前面可能少了零。原因:Excel 默认把纯数字列当数值处理,超过 11 位就用科学计数法显示,pandas 读取时如果不指定 dtype 也会转成 float。解决:读 Excel 时强制dtype=str,Excel 里提前把代码列设成文本格式,或者在代码前加一个英文单引号。导入 MySQL 时字段用 VARCHAR,别用 INT。

4.2 合并单元格导致读取时大量空值

现象:Excel 里省级名称只写一次,下面几行合并单元格,pandas 读进来只有第一行有值,其余是 NaN。原因:合并单元格在底层只有左上角单元格有值,其余是空的。解决:读进来之后用df['province'].ffill()向下填充,或者导入前在 Excel 里取消合并并补全。我一般倾向后者,因为填充逻辑依赖列顺序,容易填错列。

4.3 parent_code 截取规则和数据实际位数不匹配

现象:按code[:-2]截取上级代码,结果大量孤儿节点。原因:数据里代码位数不统一,比如有的市级代码是 4 位,有的写成了 6 位,截取规则就失效了。解决:导入前先统计代码长度分布,确认每个层级位数一致;如果不一致,先按层级分别处理,别用统一截取规则。实在乱的数据,就靠 Excel 里现成的上级代码列,别自己算。

4.4 批量插入时事务过大导致超时或锁表

现象:几十万行一次性 executemany 提交,跑到一半报连接超时或者锁等待超时。原因:单次事务太大,undo log 膨胀,或者和别的写入冲突。解决:分批提交,每 5000 到 10000 条 commit 一次;导入期间如果表上有其他写入,考虑先关掉非必要索引,导入完再重建。另外max_allowed_packet如果太小,大批量插入也会报错,适当调大。

4.5 字符集不统一导致生僻字变问号

现象:区划名称里的生僻字(比如「堠」「塅」)导入后显示成问号。原因:数据库、表、连接三处字符集不一致,或者用了 utf8 而不是 utf8mb4。解决:建库建表都用 utf8mb4,连接串里加charset='utf8mb4',Python 读 Excel 时确认文件本身编码没问题。如果已经导入错了,只能改字符集后重新导入,没有后悔药。

5. 让区划数据真正好用的两个进阶技巧

5.1 用代码前缀做层级过滤,比递归查询快一个量级

区划数据最优雅的地方在于代码本身就是层级信息。要查某个省下面所有村,不需要递归 JOIN,直接用前缀匹配就行。比如查北京市(110000)下面所有村级记录:

-- 前缀匹配拿某省下所有村级记录,走 code 索引 SELECT code, name FROM region WHERE level = 5 AND code LIKE '11%';

这条 SQL 能走主键索引的范围扫描,比递归 CTE 快得多。同理,查某市下面所有区县就是code LIKE '1101%' AND level=3。这个技巧的前提是代码严格按国家标准编码,如果数据来源不规范,前缀匹配就会出错,所以导入前的代码校验很关键。我一般会在 region 表上再建一个code_prefix生成列,把常用层级的前缀单独存出来,查询时直接等值匹配,比 LIKE 还快。

5.2 地址解析:把用户输入的乱地址映射到区划代码

区划数据落库之后最有价值的用法是地址解析。用户填的地址往往是「北京市朝阳区望京街道」这种不规范的字符串,要把它映射到区划代码,思路是先按省市区关键词做匹配,匹配到区县一级,再往下用村镇名称补全。简单实现可以用 MySQL 的全文索引或者 LIKE 逐级缩小范围,复杂一点就上分词加字典。下面是一个逐级匹配的简化版 SQL 思路,先匹配省,再在省下面匹配市,逐级往下。

-- 逐级匹配示例:先找省,再在省内找市,依次往下 SELECT code, name, level FROM region WHERE name LIKE '北京%' AND level = 1 LIMIT 1; -- 拿到省级 code 后,用 parent_code 往下查 SELECT code, name, level FROM region WHERE parent_code = '110000' AND name LIKE '朝阳%' AND level = 3 LIMIT 1;

实际做的时候,我会把每一级的匹配结果缓存起来,因为地址解析是高频操作,每次都查库扛不住。另外要注意同名区划,全国叫「城关镇」的有几百个,所以匹配必须带上级约束,不能只按名称查。这套逻辑跑通之后,用户地址就能稳定映射到区划代码,后续做区域统计、配送范围判断、门店归属都靠这个代码,比字符串匹配可靠得多。

我自己做这类项目最大的教训是:别在 Excel 里改数据。Excel 的自动格式、合并单元格、科学计数法,每一样都能让代码列悄悄变形,而且改完还不容易发现。正确的顺序永远是 Excel 只读不改,清洗和转换全在脚本里做,导入 MySQL 后跑校验 SQL,确认父子完整、代码长度一致,再开始用。这套流程跑顺了,一份 rar 包到可用的区划库,半天就能搞定。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 1:01:17

MySQL 5.7 + Java Swing 构建离线学生健康档案系统

简介:这是一套基于MySQL与Java Swing开发的学生健康档案管理系统源码,面向计算机相关专业在校生、教师及初级开发者,解决高校学生健康数据(体检病历)的结构化录入、查询、统计与导出需求,适用于课程设计、毕…

作者头像 李华
网站建设 2026/10/13 0:53:29

FlashAttention-3 前瞻:Hopper 架构异步 TMA 与 WGMMA 硬件流水线并发解密

当我们将基于 FlashAttention-2 架构调优到极致的注意力算子,移植到新一代 NVIDIA Hopper 架构旗舰显卡(H100 / H800 / H200)上时,很多工程师遭遇了一次前所未有的心理落差:在 A100 上能够跑出 73% 硬件理论峰值的代码…

作者头像 李华
网站建设 2026/10/13 0:53:11

U1981中继配置实战:SS7与SIP对接步骤与避坑指南

简介:《U1981语音网关中继配置指南.docx》是一份面向华为U1981语音网关运维与调试人员的操作手册,完整演示了统一网关与对端设备对接的中继配置过程。文档从组网场景入手,用通俗语言解释了局向、子路由、路由、局向选择码等核心概念&#xff…

作者头像 李华
网站建设 2026/10/13 0:40:33

数据仓库架构选型与维度建模实战:从分层设计到模型上线全流程

1. 数仓架构选型:为什么你的第一个决定就决定了后面三年的维护成本很多团队在启动数据仓库项目时,第一反应是“先跑起来再说”,结果半年后数据口径混乱、报表对不上、开发效率断崖式下跌。我见过太多这样的案例,根源往往不在技术本…

作者头像 李华
网站建设 2026/10/13 0:36:27

腾讯云TRTC实时音视频通话接入实战:从设计到避坑

实时音视频通话这个领域,我前前后后接触了差不多三年多,从最早做在线教育那会儿的连麦互动,到后来做远程协作工具里的屏幕共享,踩过的坑真不算少。这次想聊的是腾讯云 TRTC 的基础音视频通话接入,说白了就是把“两个人…

作者头像 李华