目录
回复内容:
数据结构
查询方法
遍历方法
优势和弱点
数据哪里来?
具体地址怎么存?
如何应对不存在的省市区名称?
首页 后端开发 php教程 你们都是怎么在数据库中存储邮政地址的?

你们都是怎么在数据库中存储邮政地址的?

Jun 06, 2016 pm 08:48 PM
mysql php

一般的邮政地址都要包含国家、省份、市县乡之类的数据,大家一般都是怎么存储的?

回复内容:

一般的邮政地址都要包含国家、省份、市县乡之类的数据,大家一般都是怎么存储的?

基本上摘自我在sf的博客文章:http://blog.segmentfault.com/shamiao/1190000000329012。

我喜欢用左右值法来组织省-市-区的表格。

数据结构

-------------------------------------
name    lbb   ubb   depth  注:ID省略
-------------------------------------
吉林省   1     14    1
长春市   2     7     2
朝阳区   3     4     3
南关区   5     6     3
辽源市   8     13    2
龙山区   9     10    3
东丰县   11    12    3
辽宁省   15    18    1
沈阳市   16    17    2
-------------------------------------
登录后复制

数据表就像这样。这个组织方法的特点是:

  • 每一个区划覆盖一个整数值区间
  • 各个区间只嵌套不交叉。
  • 甚至各区间的上下限不允许重叠,左右值是无重复的。
    这是一个相当重要的优化。下边的查询,没有这个条件基本都不能成立或不太方便。
  • 最小的区间长度至少为1。
  • 总体是一个无限嵌套的结构。

以上边这个表格为例,他表示了这样一个分层结构:

1------------------吉林-------------------14 15---辽宁---18
 2------长春------7 8--------辽源--------13    16-沈阳-17
  3-朝阳-4 5-南关-6   9-龙山-10 11-东丰-12
登录后复制

这样,省-市-区就只需要存储一个数字,即该区划的左值,就可以了。

但必须注意:虽然存左值完全够实用了,但为了数据安全,必须另开设一个字段存储对应区划的ID,作为“真正唯一的关联数据(虽然不怎么用得到)”。而左值只能当作“非常有用的冗余数据”,做好一更新随时会被重写的准备。原因末尾“优势和弱点”一节会解释。

查询方法

根据号码查询单个区划的名称,查左值相等的就行了。

如果要列出所有的上级区划,尤其方便。由于区间包含是一个简单的数学关系,所以再也不必要像典型的存储父记录号码那样,费时费力去做回溯操作。

只要把包含区间的值的所有区间取出,就是这个区划的所有上级。并且,由于大区间的左值一定比小区间的小,所以只需要按照左值升序,就可以把区间从大到小排序。

例如查询朝阳区(左值=3)的所有上级:

SELECT * FROM regiontable WHERE lbb<=3 AND ubb>3 ORDER BY lbb ASC
登录后复制

得到结果:

-------------------------------------
name    lbb   ubb   depth
-------------------------------------
吉林省   1     14    1
长春市   2     7     2
朝阳区   3     4     3
-------------------------------------
登录后复制

即吉林省-长春市-朝阳区。

遍历方法

数据表中存储了depth冗余字段代表层级深度。这个字段会在查询中起大作用。

例如列出下级所有区域(已知当前级别的左右界和深度):

SELECT * FROM regiontable WHERE lbb>左界 AND ubb<右界 AND depth=(深度+1) ORDER BY lbb ASC
登录后复制

如果列出第一级那就只查depth=1就行了。

这个查询不仅可以用于行政区划表格,也可以用于用户数据表格。例如列出属于某区域的所有用户(已知此级别的左右界):

SELECT * FROM userinfo WHERE region>=左界 AND region<右界
登录后复制

而无论对于多大的区域,这个查询效率的都是均等的高,彻底杜绝区域大了查不动。

优势和弱点

左右值法快就快在查询和排序都有数学的自然性。一步到位,无需回溯,效率是显而易见的。

而弱点同样显而易见:修改极其麻烦,并且往往是牵一发而动全身。一处写入,估计大半张表格都要跟着修改。算法就会很麻烦。

而这要注意对于任何一个记录,其左右值都是不稳定的,只能用于查询,绝对不能用来与数据表建立持久稳定的关系!这也就是前边说过一定要存区划ID的意义。

这个需求中,我们恰好使用了优势,而规避了弱点。因为行政区划数据天天查,但很少改。

数据哪里来?

要求不高的,维基百科去抄,或者到别的程序里去扒。

要求高的,去买民政部出的《中华人民共和国行政区划简册2013》,权威性没商量。

注意港澳台的行政区划问题。我建议以下的方案:

  • 香港、澳门特别行政区,仅列在中华人民共和国下,不列入单独的国家/地区。
  • 中华人民共和国下存在台湾省,但不再向下延伸;
  • 第一级国家/地区(如果有的话)单列台湾,并按维基百科资料,或参考台湾执政部门资料,填入对应的下级行政区域。最好使用正体(繁体)中文。
  • 另外,小心使用洋人做的国家列表。要是一不小心新疆和西藏单列了国家和地区,就自己考虑后果吧。

具体地址怎么存?

像淘宝那样,把省市区放在一行内,摆在地址文本框的旁边,并明示用户:地址中不必再输入省市区。

如何应对不存在的省市区名称?

我推荐的方法是:提示用户能选到多细选多细,如果再细没有了,就放在具体地址前边,一起输入到地址文本框中。

我是绝对反对整几个小文本框,给用户在找不到自己的省市区的时候,去自定义输入的。
理由也很简单:就算我们的行政区划数据库再老,再不准确,那也能保证99%的人都能找到自己的地址。
所以这个思路看似很自然(没有就自定义嘛!),但其实是在为了1%的需求投入100%的开发精力,到头来是极其愚蠢和低效的。

HTML 表格中有几个数据段, 我的数据库就相应的有几个column.

国家,省份,城市名称,我是这么干的:

plus_id, country, province, city
1      ,   中国 ,    北京  , null
2      ,   中国 ,    河北  , 廊坊
登录后复制

然后info表里关联ID就行。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP的未来:改编和创新 PHP的未来:改编和创新 Apr 11, 2025 am 12:01 AM

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

PHP与Python:了解差异 PHP与Python:了解差异 Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

mysql:简单的概念,用于轻松学习 mysql:简单的概念,用于轻松学习 Apr 10, 2025 am 09:29 AM

MySQL是一个开源的关系型数据库管理系统。1)创建数据库和表:使用CREATEDATABASE和CREATETABLE命令。2)基本操作:INSERT、UPDATE、DELETE和SELECT。3)高级操作:JOIN、子查询和事务处理。4)调试技巧:检查语法、数据类型和权限。5)优化建议:使用索引、避免SELECT*和使用事务。

phpmyadmin怎么打开 phpmyadmin怎么打开 Apr 10, 2025 pm 10:51 PM

可以通过以下步骤打开 phpMyAdmin:1. 登录网站控制面板;2. 找到并点击 phpMyAdmin 图标;3. 输入 MySQL 凭据;4. 点击 "登录"。

MySQL和SQL:开发人员的基本技能 MySQL和SQL:开发人员的基本技能 Apr 10, 2025 am 09:30 AM

MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。

php:死亡还是简单地适应? php:死亡还是简单地适应? Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

redis怎么使用单线程 redis怎么使用单线程 Apr 10, 2025 pm 07:12 PM

Redis 使用单线程架构,以提供高性能、简单性和一致性。它利用 I/O 多路复用、事件循环、非阻塞 I/O 和共享内存来提高并发性,但同时存在并发性受限、单点故障和不适合写密集型工作负载的局限性。

phpmyadmin连接mysql phpmyadmin连接mysql Apr 10, 2025 pm 10:57 PM

如何使用 phpMyAdmin 连接到 MySQL?访问 phpMyAdmin 的 URL,通常为 http://localhost/phpmyadmin 或 http://[您的服务器 IP 地址]/phpmyadmin。输入您的 MySQL 用户名和密码。选择您要连接的数据库。点击 "连接" 按钮以建立连接。

See all articles