国际地理地址应该如何存储在关系数据库中?

Bob*_*Bob 56 database-design street-address

鉴于将国际地理地址存储在关系表中的任务,最灵活的架构是什么?地址的每个部分都应该分解到自己的字段中,还是应该更像自由文本?

将不同格式的地址分成不同的表是否有任何意义?例如,有一个表USAAddress,CanadianAddress,UKAddress ...?

Ben*_*ter 93

我将从我的博客文章 - 地址存储课程中总结我的想法.

在我目前的项目[我为物流公司工作]我们存储国际地址.我在数据库的这一部分的设计中研究了世界各地的地址.有很多不同的格式.在西方世界,我们倾向于使用相当统一的格式 - 一些差异,但它们主要是:

  • 街道号码 - 数字
  • 房屋或建筑物名称 - [VarChar - 在英国,一些房屋/建筑物按名称而不是数字标识]
  • 街道号码后缀 [VarChar,虽然在大多数情况下,Char(1)就足够了]
    • A,B等
  • 街道名称 [VarChar]
  • 街道类型 [如果您有StreetTypes表,则为VarChar或Int]
    • 到目前为止,我在英语世界中发现了262种独特的类型,可能更多,不要忘记其他语言,如Strasse,Rue等.
  • 街道方向 [VarChar(2)]
    • N,E,S,W,NE,SE,NW,SW
  • 如果你有一个AddressTypes表,地址类型 [VarChar或Int]
    • 邮政信箱
    • 公寓
    • 建造
    • 地板
    • 办公室
    • 套房
    • 等等...
  • 地址类型标识符 [VarChar]
    • 即箱号,公寓号码,楼层号码记住公寓号码和办公室有时会有字母数字信息 - 如1A
  • 当地市政府 [VarChar或Int,如果您有市政府表]
    • 例如,如果您的小村庄/村庄出现在城镇之前的地址中.
  • 城市/城镇 [如果您有城市表,则为VarChar或Int]
  • 管理区 [VarChar或Int,如果您有区域表]
    • 州(美国)
    • 省(加拿大)
    • 联邦区(墨西哥)
    • 郡(英国)
    • 等等...
  • 邮政区 [VarChar]
    • 邮编(美国)
    • 邮政编码(加拿大,墨西哥)
    • 邮政编码(英国)
  • 国家 [如果您有国家/地区表,则为VarChar或Int]

这似乎涵盖了大多数国家/地区,但字段的顺序可能会以不同方式显示.您可以在http://www.bitboost.com/ref/international-address-formats.html#Formats找到显示格式列表

例如,在许多国家/地区,邮政编码位于城市名称之前,街道编号位于街道名称之后.在加拿大,美国和英国,街道号码位于街道名称之前,邮政编码(或ZIP)位于城市名称之后.

在回答你关于将地址分成不同国家的问题时,我不会建议,它只会使其他领域的生活更加艰难 - 例如报道.我提供的格式涵盖了我们的物流数据库中的所有地址,其中包括美国,加拿大,墨西哥和英国,没有任何问题.它还涵盖了我们所有的欧洲,中国,日本和马来西亚地址.我不能代表其他国家发言,但我还没有必须存储这些领域不支持的国家的地址.

我不建议使用其他人建议的Address1,Address2,Address3格式,并在许多数据库中看到,因为从字母数字字符串中解析地址信息并不像看起来那么简单 - 特别是如果没有正确输入数据,由于错误信息,拼写错误,拼写错误等.如果你分开你的字段,你可以使用距离算法检查可能的含义,使用概率检查街道名称与邮政编码和街道号码或检查省和城市的街道名称等.尝试当你有一个字符串表示你的整个街道地址时,做任何这些.任何想象力都不是一件小事.

关于地址数据库的质量保证是一个令人头痛的问题.简化此区域生活的最简单方法是确保所有字段仅包含一条信息,可在入口时自动验证为正确.概率,距离算法和正则表达式可以检查输入的有效性,并向用户提供关于他们的错误的反馈并建议适当的更正.

需要注意的一个警告是道路的名称也是街道类型 - 如果你覆盖加拿大,你需要注意多伦多的"大道路",如果你使用地址1,2,这将使你绊倒很长时间,3格式.这可能也发生在其他地方,虽然我不知道它们 - 这个单一实例足以让我尖叫WTF?!

  • 您如何处理从用户请求此信息?你真的有这么多领域供他们阅读和破译吗?我理解它的必要性,但是还需要保持数据输入对用户来说非常简单,特别是当棘手的表单可能会让您失去销售或新成员时. (6认同)
  • @DeveloperChris问题的标题询问"国际*地理地址应该如何存储在关系数据库中",因此您的评论在这种情况下基本上无关紧要. (5认同)
  • @DeveloperChris `希望在本地和国际上获得指导的人们都会查看此主题。底线。`然后他们看错了问题。底线。 (3认同)
  • @Thomas - 大量的搜索和列表保存。澳大利亚、英国、爱尔兰、加拿大、美国、海峡群岛、法国。如果没有获得每个国家的邮政数据库,这是一项艰巨的任务。 (2认同)

Rub*_*ben 21

注意不要过度分析地址格式.当你这样做时,你很可能最终得到大多数用户需要解决的规范,有效地迫使他们使用错误的字段,或只填充主要字段并忽略额外的字段.

保持简单.

当你开始使用与英语或西班牙语等隔离语言不同的语言时,BenAlabaster提到的StreetType会引起问题.

为了向您展示在野外会有多糟糕的事情:阿姆斯特丹的"Henriette Roland Holststraat",由"Henriette"+"Roland Holst"+"straat"构成,可以缩写为"Roland Holststraat",或者" Roland Holststr."或拼错为"HRHolststr." 或"Henriette Roland-Holst straat",视天气而定.除非你有一个地球上每个国家的最新街道登记册,否则你将无处可去.

最后,请注意,在某些多语言国家,名称可能因语言而异!例如在布鲁塞尔,许多街道都有法语荷兰语名称:"Avenu du Port"和"Havenlaan",取决于收件人的首选语言.(谷歌地图交替显示两个名称,只是为了安全起见.)

你可以尝试在这里设计各种聪明的技巧,但是销售代表.会明白这个吗?

  • 你确实提出了一个很好的观点,我没有在我的回答中提到。在考虑荷兰语、德语和其他非隔离语言时,这当然是应该考虑的事情。 (2认同)

Ste*_*ton 8

这取决于你想用它做什么.

我发现如果将地址用于其他目的(例如针对USPS数据的验证或从UPS/FEDEX获得运费),如果它们是分开的,则总是更容易.

这是我通常用于地址的内容:

  • 地址第一行
  • 地址第2行
  • 地址第3行
  • 区域
  • 邮政编码
  • 国家

响应编辑: 在大多数情况下,我没有看到使用.上面列出的表格对于大多数国家/地区的地址都有足够的字段(并且足够通用).

  • @Alix Axel - 对于这些国家,将该字段留空 (2认同)

Stu*_*Tea 8

对于偶然发现这个问题的人,这里有一个轶事:

我作为一个在许多大陆(欧洲、亚洲、北美)生活和工作过的人发言。根据我的经验以及与我共事的人的经验,我们使用具有以下功能的系统要容易得多:

  1. 提供三行,我将在其中键入一个地址。当我输入它们时,将这三行逐字传递给您当地的邮政服务。让我使用任何我想要的字符集;使用 UTF-8 或更好的东西。
  2. 如果您的系统有业务需求需要我指定特定信息(例如邮政编码、县、州等),请单独询问。对于业务需求,我指的是分析之类的东西;这些信息不应与您当地的邮政服务共享(除非我也碰巧将相同的信息写入了上面第 1 点的三行之一)。
  3. 有一个下拉菜单,要求我指定我在上面第 1 点的行中提供的地址的分类位置,可能是 Country。
  4. 如果您必须解析我在第 1 点行中提供的信息,请使用我对第 3 点的回答来选择正则表达式。针对第 1 点中的信息运行该正则表达式以解析它。尝试使用正则表达式的输出填充第 2 点的用户界面元素。如果我更正了自动填充的信息 - 使用我更改它以改进您的正则表达式的事实。同样,尽可能多地给我一个机会来检查和纠正你的正则表达式的输出:没有人比我更清楚我打算传达什么。

我发现,像这样构建的系统让我的生活更轻松。特别是当我将邮件发送到贵公司几乎没有内部功能知识的邮政系统时。

如果您的公司确实拥有有关特定邮政系统的内部知识,请使用我在第 3 点中的选择来告知您向我显示的视图。很多人都知道美国邮政系统对包装的要求;如果我在第 3 点中选择美国,请随意使视图看起来适合美国地址。如果我选择一个你的公司一无所知的国家——显示一个通用的三行,剩下的让我做;不要强迫我使用 ASCII。

让我们成为现实——建立一个完整的、涵盖所有全球邮政系统(公共和私人)的百科全书数据库是一项艰巨的任务,即使不是不可能的。例如,在邮政系统中,只有当地的最后一英里承运人才真正知道地址所在的位置。有时能够在包装上将票据传递给该承运人是非常有用的。将每个边缘案例载体的本地知识映射到您的数据库中确实是一项不可能完成的任务。

问问哥德尔就知道了。(然后问问自己,您是否正在尝试使用公理系统来模拟一个话语世界,给出或接受某种算术,如集合论或关系代数。)


ryb*_*111 6

地址

与@BenAlabaster提供的优秀答案完全相反,您可以简单地:

address       TEXT(300)
postal_code   VARCHAR(15)
country_code  VARCHAR(2)
Run Code Online (Sandbox Code Playgroud)

您的客户端表单布局仍然可能是您认为合适的复杂(或使用多行输入,用户可以手动键入其地址).然后,您可以在必要时在地址中添加换行符.

国家

您的国家/地区表格如下所示:

country_code  VARCHAR(2)
country_name  VARCHAR(255)
Run Code Online (Sandbox Code Playgroud)

此外,您可以拥有以下其中一项:

postal_code_required  TINYINT(1)
postal_code_regex     VARCHAR(255) NULL DEFAULT NULL
Run Code Online (Sandbox Code Playgroud)

然后使用以下列表设计您的国家/地区表: