在数据库(RDBMS)中存储邮政地址的最佳做法?


106

是否有关于在RDBMS中存储邮政地址的最佳做法的良好参考?似乎可以做出很多权衡,要评估每个优点和缺点的优点-当然,这一次又一次地完成了吗?也许有人至少在某个地方写了一些功课来写作?

我正在讨论的权衡示例是,将邮政编码存储为整数而不是char字段,应该将门牌号存储为单独的字段或地址行1的一部分,还是应该对套件/公寓/等号码进行规范化或仅将其存储为地址行2中的大量文本,您如何处理zip +4(单独的字段或一个大字段,整数还是文本)?等等

目前,我主要关注的是美国地址,但我想有一些最佳做法可以为将来走向全球做准备(例如,适当地命名字段,例如区域,而不是州或邮编,而不是邮政编码,等等


3
bat zip必须是一个char字段-否则某些以0开头的邮政编码会变得不正确。
Menasheh '17

1
根据经验,当您需要使用数字进行数学计算时,它应该是整数。如果仅显示,则应为char(电话,邮政编码等)
Zikato

Answers:


37

对于更多的国际使用,Drupal Address Field使用的是一种要考虑的模式。它基于xNAL标准,似乎涵盖了大多数国际案例。对该模块进行一些深入的研究将发现一些不错的明珠,可用于在国际范围内解释和验证地址。它还具有一组带有ISO代码的行政区域(省,州,州等)。

这是从模块页面复制的架构要点:

country => Country (always required, 2 character ISO code)
name_line => Full name (default name entry)
first_name => First name
last_name => Last name
organisation_name => Company
administrative_area => State / Province / Region (ISO code when available)
sub_administrative_area => County / District (unused)
locality => City / Town
dependent_locality => Dependent locality (unused)
postal_code => Postal code / ZIP Code
thoroughfare => Street address
premise => Apartment, Suite, Box number, etc.
sub_premise => Sub premise (unused)

我学到的教训:

  • 不要以数字形式存储任何内容。
  • 尽可能将国家和行政区域存储为ISO代码。
  • 当您不知道时,请放宽对必填字段的要求。某些国家/地区可能不会使用您视为理所当然的字段,即使是locality&之类的基本内容也是如此thoroughfare

1
请问“ name_line”的用途是什么?我在Drupal Docs或xNal Standard中找不到真正的解释。据我了解,name_line用于通过邮件发送真实的信件或包裹。该FIRST_NAME / 姓氏,如果你想直接通过电子邮件地址的客户,比如只需要(“亲爱的先生<姓氏>”)。还是有其他目的/好处?
luba

当传递到(大型)商业场所时,内部邮件传递系统通常需要一个名称(考虑带邮件室的办公楼)
克里斯·布朗

24

作为“国际”用户,没有什么比处理仅针对美国格式地址的网站更令人沮丧的了。起初有点不礼貌,但是当验证也过于热情时,这便成为一个严重的问题。

如果您担心要全球化,那么我唯一的建议就是保持事物自由形态。不同的国家/地区有不同的约定-在某些地方,门牌号在​​街道名称之前,在某些地方则在街道名称之后。有些州,州,某些县,或这些州的某些组合。在英国这里,邮政编码不是邮政编码,而是包含字母和数字的邮政编码。

我建议您只建议输入10行左右的可变长度字符串,并为邮政编码提供一个单独的字段(请注意,如何描述它以适应国家的敏感性)。让用户/客户决定如何写他们的地址。


就其价值而言,这不是针对网站的,但是关于国际地址的观点仍然被很好地接受。
约翰,

46
尽管我不同意此消息,但实际上我为您的立场表示赞赏,但我不得不对您投反对票,因为我讨厌这样的事实,即我花费大量时间编写工具来清理地址数据以自由格式存储地址数据。地址的格式可能不同,但是数据仍然基本相同。在街道名称之前或之后显示街道编号在很大程度上与存储目的无关-仅出于显示目的。
BenAlabaster

20

如果您需要有关其他国家/地区如何使用邮政地址的全面信息,请参见以下很好的参考链接(哥伦比亚大学):

弗兰克的邮政强制性指南
解决了国际邮件的有效地址问题


17

由于特殊情况(例如“半数”或我的当前地址,例如“ 129A”),您绝对应该考虑将门牌号存储为字符字段而不是数字。但是,A不能视为公寓送货服务编号。


11

我已经做到了(严格地在数据库中对地址结构进行建模),我再也不会做。您无法想象必须将例外情况考虑在内是多么疯狂。

我隐约记得挪威邮编的一些问题(我认为),除了奥斯陆(大约有18个)外,这四个职位都是四个职位。

我可以肯定地说,从我们开始对所有本国地址使用地理上正确的邮政编码的那一刻起,就有很多人开始抱怨他们的邮件来不及了。原来这些人住在邮政区之间的边界附近,尽管事实上有人确实住在邮政区,例如1600,实际上他的邮件应该寄给邮政区1610,因为实际上这是邻近的邮政区因为实际上是为他服务的,所以将他的邮件发送到他正确的邮政区域会花费几天的时间,因为正确的邮政局需要进行不必要的干预才能将其转发到错误的邮政区域...

(我们最终用ISO代码“ ZZ”注册了在该国国外地址的人员。)


8

您当然应该咨询“ 这是在关系数据库中对地址信息进行建模的一种好方法 ”,但是您的问题不是该问题的直接重复。

肯定有很多预先存在的答案(例如,在DatabaseAnswers中查看示例数据模型)。在某些情况下,许多先前存在的答案都是有缺陷的(根本就没有选择DB Answers)。

要考虑的一个主要问题是地址的范围。如果您的数据库必须处理国际地址,则必须比只处理一个国家/地区的地址更加灵活。

在我看来,记录地址的“地址标签图像”并分别分析内容通常(但并不总是意味着)是明智的。这使您可以处理邮政编码位置之间的差异,例如,不同国家之间的差异。当然,您可以编写一个分析器和一个格式化程序来处理不同国家的异常情况(例如,美国地址有2或3行;相比之下,英国地址可以有更多行;我经常写的一个地址有9行)。但是,让人们进行分析和格式化并让DBMS仅存储数据会更容易。


7

除非您要对街道号码或邮政编码进行数学运算,否则将它们存储为数字只会引起将来的麻烦。

您可能会在这里和那里保存一些字节,并且可能会获得更快的索引,但是当美国邮政或您正在处理的任何其他国家/地区决定在代码中引入字母时,您会怎么做?

磁盘空间的成本将比以后修复它的成本便宜得多。y2k有人吗?


7

除了@ Jonathan Leffler和@ Paul Fisher所说的之外

如果您希望将加拿大或墨西哥的邮政地址添加到您的要求中,postal-code则必须将其存储为字符串。加拿大有字母数字邮政编码,我不记得墨西哥的样子。


7

艾夫发现,列出从最小离散单位到最大离散单位的所有可能字段是最简单的方法。用户将填写他们认为合适的字段。我的地址表如下所示:

*********************************
  Field              Type
*********************************
  address_id (PK)    int
  unit               string
  building           string        
  street             string
  city               string
  region             string
  country            string
  address_code       string
*********************************

您如何存放邮政信箱?
Jowen 2015年

只需添加另一列PO_box即可。如果必须进行追溯,则意味着以前的地址都不需要PO Box,因此可以将其设置为null
Gaz_Edge 2015年

2

将ZIP存储为NUMBER或VARCHAR时的“权衡”在哪里?这只是一个选择-除非两者都有好处,而且您必须放弃一些好处才能获得其他好处,否则这不是一个折衷的选择。

除非拉链的总和完全没有意义,否则将数字作为邮政编码是没有用的。


一种折衷方案可能是数据库大小。在mysql 5中,mediumint行每行仅占用3个字节,而varchar(5)将占用两倍。我还认为数字搜索比文本搜索快,但我对此并不乐观。
gpojd

4
一个应该使用varchar。加拿大邮政编码使用字母数字编码,该数字不太适合数字。
EvilTeach

1
尽管我的确理解了使用varchar的“前向兼容”逻辑,但是“按数字压缩没有用”这一说法有点过于教条。如果您知道要使用仅限美国的邮政编码,则将邮政编码存储为整数是很有意义的,就像使用严格类型的语言编写时一样,您不必将所有内容都定义为String类型。知道这将是一个数字,为​​什么不依靠数据库/编程语言的类型检查并将其称为“整数”呢?
rinogo 2013年

1
@rinogo使用varchar的一个论据是,在数学意义上邮政编码不是数字。对它们进行加或减是没有意义的;它们仅使用受限字符集进行编码。 stackoverflow.com/a/893489/48659
史蒂夫·弗利

1
@SteveFolly为了进一步支持Zip代码为字符串,前导字符具有特殊的意义:en.wikipedia.org/wiki/ZIP_Code#Primary_state_prefixes如果要实现诸如“值的最左字符是什么”这样的逻辑?那么听起来肯定更像是字符串,而不是整数。
David Aldridge

2

这可能是一个矫kill过正的做法,但是如果您需要一个可以在多个国家/地区使用的解决方案,并且需要以编程方式处理部分地址:

您可以使用两个表来处理特定于国家/地区的地址:一个具有10个VARCHAR2列,10个Number列的通用表,另一个将这些字段映射到提示的表,并且有一个country列将一个地址结构绑定到一个国家。


我实际上已经考虑过自己。除了(也许不是代替)根据国家/地区将列映射到提示的表格之外,我正在考虑为每种特定的地址格式创建可更新的视图。尚未触发,但已经考虑了。
安德鲁·斯蒂兹

1

如果您必须验证地址或使用它来处理信用卡付款,则至少需要一些结构。一个自由格式的文本块不能很好地解决这个问题。

邮政编码是一个通用的可选字段,用于在不使用整个地址的情况下验证支付卡交易。因此,请为此设置一个单独且大小足够的字段(至少10个字符)。



-2

我只是将所有字段放在一起放在一个大的NVARCHAR(1000)字段中,并带有一个textarea元素供用户输入其值(除非您想对邮政编码进行分析)。如果您的地址与该格式不太匹配(并且您知道美国以外的其他国家/地区),那么所有这些地址行1,地址行2等输入都非常令人讨厌。


3
多么可怕的主意!“注释”中没有足够的空间来描述此邀请的噩梦。最好花一些额外的时间正确地设计它,而不是在以后弄乱它们。请参阅Samm Cooper的答案。我想我只是在这里对其他答案投了反对票,但是这个答案肯定赢得了我的反对。
安德鲁·斯蒂兹

哪个烂摊子?您需要什么数据?通常,您只需要将其直接传递给某些标签打印机或类似打印机,然后就可以将其视为一小段文本。其他时候,您可能会关心城市和邮政编码(但最好确保那时只有在受支持国家/地区的客户)
erikkallen

2
OP并未提及“仅需要将其传递给标签打印机”,在我做过的每一项工作中,我们都使用该地址作为“数据”,运行报告,收取税款(科罗拉多州将用于新房屋的家电的营业税) (从街道的一侧到另一侧不等),将销售线索分配给销售人员,满足政府的合规性要求,清单就此不断。“销毁”数据(通过将不同的项目混入一个字段或不捕获可用数据)是我书中的“罪过”,并且一直被证明是人们忽视我时我所警告的噩梦。
安德鲁·斯蒂兹

如果以后发现不需要数据,则可以以后随时“销毁”它。“创建”数据的范围从噩梦(将信息拆分到单独的字段中)到不可能(在事实发生后捕获数据)。如果OP表示“只需要将其发送到标签打印机”,我会为您的回答表示赞赏和赞成。但是,在没有具体提及“销毁”数据的建议的情况下,IMO濒临不负责任甚至卑鄙的边缘。
安德鲁·斯蒂兹

在我工作过的地方(主要是电子商务),我们倾向于将其存储在5-6个不同的字段中,但是我们永远不会对信息进行任何处理,而只是使用它来进行发送。
erikkallen's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.