SELECT c.id, c.name
FROM cn_area a
JOIN cn_area b ON b.id BETWEEN a.cid_begin AND a.cid_end AND b.level=1AND b.name LIKE'%深圳%'JOIN cn_area c ON c.id BETWEEN b.cid_begin AND b.cid_end AND c.level=2WHERE a.level=0AND a.name LIKE'%广东%';
速度
数据库
表大小
用时
SQLite
3640 行,无索引,84 KB
0.006 秒
结果
id
name
440301000000
市辖区
440303000000
罗湖区
440304000000
福田区
440305000000
南山区
440306000000
宝安区
440307000000
龙岗区
440308000000
盐田区
440309000000
龙华区
440310000000
坪山区
440311000000
光明区
2. 不能在前端查询数据嘛?
2.1 作为数据库提供
SQLite 有提供 wasm 版,可不依赖后端就能完成查询
整个数据库大小才 84 KB,gzip 压缩后 42 KB,感觉代价不算大?
2.2 作为 json 提供
使用以下 SQL:
SELECT json_group_object(format('%d,%s', a.id, a.name),(SELECT json_group_object(format('%d,%s', b.id, b.name),(SELECT json_group_object(format('%d,%s', c.id, c.name), json('{}'))FROM cn_area c
WHERE c.level=2AND c.id BETWEEN b.cid_begin AND b.cid_end))FROM cn_area b
WHERE b.level=1AND b.id BETWEEN a.cid_begin AND a.cid_end))FROM cn_area a
WHERE a.level=0;
WITH RECURSIVE
query(id)AS(VALUES(110101000000)),
parent_of(id, path)AS(SELECT pid, name
FROM query
JOIN cn_area USING(id)UNIONALLSELECT pid, name || path
FROM parent_of
JOIN cn_area USING(id))SELECT path
FROM parent_of
WHERE id =0;
SELECTformat('%d: %s%s%s%s%s', a.id, e.name, d.name, c.name, b.name, a.name)FROM cn_area a
LEFTJOIN cn_area b ON b.id = a.pid
LEFTJOIN cn_area c ON c.id = b.pid
LEFTJOIN cn_area d ON d.id = c.pid
LEFTJOIN cn_area e ON e.id = d.pid;
没看明白,区/县编号不是包含了省市编号了吗,为什么还要查三次
省市区县放在一行,就是最小颗粒度是区/县,搜索?这么少的数据,你太小看数据库的性能了
存 省份ID,城市ID,县区ID,同时在修改时把省份城市县区名称做冗余字段
{"province_name":"北京","city_name":"北京市","district_name":"朝阳区"}
用于展示,既方便检索,有在展示的时候不用关联表获取区域名称,唯一缺点就是区域名称发生变更无法及时更新用一张表加个字段parent_id父级id
用国家统一行政区域划分代码
110110113 每3位拆开。 110北京市110北京市113顺义区
中华人民共和国民政部发布的行政区划代码: www.mca.gov.cn/article/sj/xzqh/202...
uid , uname, 省, 市 ,县
前端筛选的时候,后端把区域数据做个级联类型返回,这样前端筛选时,传过来的就是id
e.g.:
我们用的每个字行政区都是有拼上上级行政区的, 比如 朝阳区冗余了北京北京市朝阳区 北京市冗余了北京北京市 存三个字段 但楼上说的国家统一行政区域划分代码也挺不错的
前端、数据库新手,好奇问一下:
1. 这种表结构不行嘛?
其中,
parent_id
、child_id_begin
、child_id_end
都可自动生成1.1 查询广东深圳下的所有区
SQLite
代码速度
SQLite
结果
2. 不能在前端查询数据嘛?
2.1 作为数据库提供
SQLite
有提供wasm
版,可不依赖后端就能完成查询整个数据库大小才 84 KB,
gzip
压缩后 42 KB,感觉代价不算大?2.2 作为
json
提供使用以下
SQL
:输出格式化后的
json
(大小:106 KB,gzip
后 27 KB):js
查询结果
一般存IP在需要的时候再查
@臭鼬 噢,我贴一下如何生成这个 66W 行数据库的备忘。(若你感兴趣,也可花一两分钟试一试)
下载并解压大佬爬好的数据:raw.githubusercontent.com/zhiguang...
运行下列
SQL
,等待几秒钟,即可生成new.db
(3 级数据为 84 KB,5 级数据为 16.8 MB):(下面是
bash
脚本示例)用户表字段。只存一个字段较好,因为北京直辖是没有第三级区级 code 的。
地区文字显示及地名模糊搜索。地区代码表增加全称冗余,如某省某市、某省某市某县。
三级联动。1/不查库,直接缓存全三级数据,或缓存前两级省级地级。2/查库,地区代码表加 level 字段省级1地级2区级3,由上一级向下一级查时,去掉各级的数字位,如省查市以河北为例,前两位13为省级位,
like 13% and level = 2
,地级查区级以石家庄市为例,前四位为地级,like 1301% and level=3
。由下一级查上一级,如 130102 为例(石家庄市长安区),那么省级 code 为 13+0000,地级 code 为 1301+00,
select id,code,level from areas where code in (130102, 130100, 130000)
,再以 level 字段区别三级。太多的简单问题复杂化
用MySQL视图可以试试,比如区县视图,包含省市区
懒加载
这个不就是无限分级么 一个表就行 有个关键的uuid与pid就行 uuid pid name
id(自增) code(非重) name(北京) alias_name(京) level (province,city,county,town,) 四级 pid(省默认为0), province_id, province_name, city_id, city_name, county_id, county_name, town_id, town_name, area_path(北京市--北京市--xx区--xx街道--xx)
最后输出的时候 Transformer 遇到 北京市--北京市的这种情况 直接删除一个