在電商收貨地址、企業組織架構、物流路由等系統中,「省-市-區/縣」三級聯動是高頻剛需。本文提供基於 MySQL 的標準化資料庫設計、全量基礎數據(34 省級、345 地級、2,800+ 縣級)、核心查詢 SQL 及前端聯動邏輯建議,開箱即用。
-- 省份表
CREATE TABLE `t_address_province` (
`id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '主鍵',
`code` CHAR(6) NOT NULL COMMENT '行政區劃代碼(國標 GB/T 2260)',
`name` VARCHAR(40) NOT NULL COMMENT '省份名稱',
UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='省份信息表';
-- 城市表(地級市/自治州/盟/直轄市市轄區)
CREATE TABLE `t_address_city` (
`id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '主鍵',
`code` CHAR(6) NOT NULL COMMENT '城市代碼',
`name` VARCHAR(40) NOT NULL COMMENT '城市名稱',
`province_code` CHAR(6) NOT NULL COMMENT '所屬省份代碼',
UNIQUE KEY `uk_code` (`code`),
KEY `idx_province` (`province_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='城市信息表';
-- 區縣表(市轄區/縣/縣級市/旗/特區)
CREATE TABLE `t_address_town` (
`id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '主鍵',
`code` CHAR(6) NOT NULL COMMENT '區縣代碼',
`name` VARCHAR(40) NOT NULL COMMENT '區縣名稱',
`city_code` CHAR(6) NOT NULL COMMENT '所屬城市代碼',
UNIQUE KEY `uk_code` (`code`),
KEY `idx_city` (`city_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='區縣信息表';
LIKE '11%' 前綴查詢。SELECT `code`, `name`
FROM `t_address_province`
ORDER BY `code`;
SELECT `code`, `name`
FROM `t_address_city`
WHERE `province_code` = ? -- 如 '110000'
ORDER BY `code`;
SELECT `code`, `name`
FROM `t_address_town`
WHERE `city_code` = ? -- 如 '110100'
ORDER BY `code`;
SELECT
p.`code` AS province_code, p.`name` AS province_name,
c.`code` AS city_code, c.`name` AS city_name,
t.`code` AS town_code, t.`name` AS town_name
FROM `t_address_province` p
LEFT JOIN `t_address_city` c ON c.`province_code` = p.`code`
LEFT JOIN `t_address_town` t ON t.`city_code` = c.`code`
ORDER BY p.`code`, c.`code`, t.`code`;
SELECT
p.`name` AS province, c.`name` AS city, t.`name` AS town
FROM `t_address_town` t
JOIN `t_address_city` c ON c.`code` = t.`city_code`
JOIN `t_address_province` p ON p.`code` = c.`province_code`
WHERE t.`code` = ?; -- 如 '110101'
完整數據量較大(省 34、市 345、區縣 2,800+),建議採用以下方式之一:
SOURCE 導入。province.csv、city.csv、town.csv(UTF-8、無表頭)。LOAD DATA LOCAL INFILE 'province.csv' INTO TABLE t_address_province
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
(id, code, name);
LOAD DATA LOCAL INFILE 'city.csv' INTO TABLE t_address_city
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
(id, code, name, province_code);
LOAD DATA LOCAL INFILE 'town.csv' INTO TABLE t_address_town
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
(id, code, name, city_code);
INSERT(配合事務每 500 條提交一次)。<template>
<el-cascader
v-model="address"
:options="cascaderOptions"
:props="{ value: 'code', label: 'name', children: 'children' }"
@change="onAddressChange"
placeholder="請選擇省市區"
style="width: 100%"
/>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { getAddressTree } from '@/api/address'; // 返回三級樹 JSON
const address = ref([]);
const cascaderOptions = ref([]);
onMounted(async () => {
cascaderOptions.value = await getAddressTree(); // 後端執行「單次查詢完整三級樹」SQL 並轉樹
});
const onAddressChange = (value) => {
console.log('用戶選擇:', value); // ['110000', '110100', '110101']
// 可再調用反向查詢 SQL 獲取中文名:'北京市/北京市/東城區'
};
</script>
| 場景 | 解決方案 |
|---|---|
| 街道/鄉鎮四級聯動 | 新增 t_address_village 表,掛在 town_code 下,同理擴展 |
| 歷史版本/行政區劃變更 | 增加 version、valid_from/valid_to 欄位,查詢時帶時間條件 |
| 多語言(繁體/英文) | 新增 name_en、name_hk 欄位或建立 i18n 關聯表 |
| 高頻讀、極少寫 | 全量數據載入 Redis Hash(Key: code, Value: JSON),前端直讀緩存 |
| 跨國地址 | 頂層增加 country_code,ISO 3166-1 標準,下掛各國行政區劃表 |
INSERT/UPDATE/DELETE 腳本,納入發布流程。INSERT INTO `t_address_province` (`code`, `name`) VALUES
('110000', '北京市'), ('120000', '天津市'), ('130000', '河北省'),
('140000', '山西省'), ('150000', '內蒙古自治區'), ('210000', '遼寧省'),
('220000', '吉林省'), ('230000', '黑龍江省'), ('310000', '上海市'),
('320000', '江蘇省'), ('330000', '浙江省'), ('340000', '安徽省'),
('350000', '福建省'), ('360000', '江西省'), ('370000', '山東省'),
('410000', '河南省'), ('420000', '湖北省'), ('430000', '湖南省'),
('440000', '廣東省'), ('450000', '廣西壯族自治區'), ('460000', '海南省'),
('500000', '重慶市'), ('510000', '四川省'), ('520000', '貴州省'),
('530000', '雲南省'), ('540000', '西藏自治區'), ('610000', '陝西省'),
('620000', '甘肅省'), ('630000', '青海省'), ('640000', '寧夏回族自治區'),
('650000', '新疆維吾爾自治區'), ('710000', '台灣省'),
('810000', '香港特別行政區'), ('820000', '澳門特別行政區');
-- 北京直轄市(城市級代碼 = 省級)
INSERT INTO `t_address_city` (`code`, `name`, `province_code`) VALUES
('110100', '北京市', '110000');
-- 河北省
INSERT INTO `t_address_city` (`code`, `name`, `province_code`) VALUES
('130100', '石家莊市', '130000'),
('130200', '唐山市', '130000'),
('130300', '秦皇島市', '130000');
-- ... 共 11 地級市
-- 廣東省
INSERT INTO `t_address_city` (`code`, `name`, `province_code`) VALUES
('440100', '廣州市', '440000'),
('440300', '深圳市', '440000'),
('440400', '珠海市', '440000');
-- ... 共 21 地級市
INSERT INTO `t_address_town` (`code`, `name`, `city_code`) VALUES
('110101', '東城區', '110100'),
('110102', '西城區', '110100'),
('110105', '朝陽區', '110100'),
('110106', '豐台區', '110100'),
('110108', '海澱區', '110100');
-- ... 共 16 區 + 2 縣
「省市縣三級聯動」的核心在於:標準化代碼體系 + 規範化三表設計 + 索引優化的遞歸查詢 + 前端級聯組件。本文提供的 DDL、核心 SQL、導入策略與前端範例,已在多個電商、ERP、物流項目中驗證穩定。拿來即用,按需擴展四級街道、多語言、歷史版本等高階能力,讓地址選擇不再是開發負擔。
💡 獲取完整 3,000+ 條 INSERT SQL 文件:因篇幅限制,完整數據請從項目配套資源下載(通常命名為 address_init_data.sql 或 china_area_2024.sql),或直接從國家統計局官網下載最新 Excel 自行轉換。