使用整数列将美国邮政编码存储在数据库中是一个好主意吗?

时间:2009-05-21 15:10:22

标签: database database-design types street-address postal-code

从第一眼看,似乎我有两个基本选择将ZIP codes存储在数据库表中:

  1. 文字(可能是最常见的),即支持+4扩展的char(5)varchar(9)
  2. 数字,即32位整数
  3. 如果我们假设没有国际问题,那么两者都将满足数据的要求。在过去,我们通常只是走了文本路线,但我想知道是否有人做相反的事情?只是简单的比较看起来整数方法有两个明显的优点:

    • 就其本质而言,它仅仅自动限于数字(而没有验证,文本样式可以存储字母,据我所知,这些字母在邮政编码中无效)。这个意味着我们可以/愿意/应该放弃正常验证用户输入!
    • 它占用的空间更少,为4个字节(即使对于9位邮政编码也应该足够),而不是5或9个字节。

    此外,它似乎不会对显示输出造成太大影响。在数字值上打ToString(),使用简单的字符串操作来插入连字符或空格或+4扩展名的任何内容都是微不足道的,并使用字符串格式来恢复前导零。

    是否有任何阻止使用int作为仅限美国邮政编码的数据类型的内容?

11 个答案:

答案 0 :(得分:112)

数字邮政编码 - 在很小的程度上 - 具有误导性。

数字应该表示 numeric 。邮政编码不会添加或减少或参与任何数字操作。 12309 - 12345不计算从斯克内克塔迪市中心到我家附近的距离。

当然,对于邮政编码,没有人感到困惑。但是,对于其他类似数字的字段,它可能会令人困惑。

由于邮政编码不是数字 - 它们恰好用限制字母编码 - 我建议避免使用数字字段。 1字节的保存不值得。我认为意味着比字节更重要。


修改

“至于领先零......”是我的观点。数字没有前导零。在邮政编码上存在有意义的前导零是另一个证明它们不是数字的证明。

答案 1 :(得分:24)

您是否会存储非美国邮政编码?加拿大有6个字符,有些字母。我通常只使用10个字符的字段。磁盘空间很便宜,不得不重新编写数据模型。

答案 2 :(得分:17)

使用带验证的字符串。邮政编码可以从0开始,因此数字不是合适的类型。此外,这适用于国际邮政编码(例如英国,最多8个字符)。如果邮政编码是瓶颈,则可以将其限制为10个字符,但请先检查target formats

英国,美国和加拿大的

Here are验证正则表达。


是的,您可以填充以获得前导零。但是,理论上你丢弃了可能有助于发生错误的信息。如果有人在数据库中找到1235,原来是01235,还是错过了另一个数字?

最佳实践说你应该说出你的意思。邮政编码是代码,而不是数字。你要去add/subtract/multiply/divide邮政编码吗?从实际角度来看,排除延长拉链更为重要。

答案 3 :(得分:9)

通常,您将使用非数值数据类型,例如varchar,这将允许更多的邮政编码类型。如果你只是允许5位[XXXXX]或9位[XXXXX-XXXX]邮政编码,你可以使用char(5)或char(10),但我不推荐它。 Varchar是最安全,最理智的选择。

编辑:还应注意,如果您不打算对该字段进行数值计算,则不应使用数值数据类型。在您添加或减少邮政编码的意义上,邮政编码不是一个数字。它只是一个恰好由数字组成的字符串,所以你应该避免使用数字数据类型。

答案 4 :(得分:7)

从技术角度来看,这里提出的一些观点相当微不足道。我在每日的基础上处理地址数据清理 - 特别是来自世界各地的清理地址数据。任何想象力都不是一项微不足道的任务。对于邮政编码,可以将它们存储为整数,尽管它可能不是“语义上”正确的。事实是,数据是否为数字形式,严格来说, 在数值上被视为数值。

但是,将它们存储为数字类型的真正缺点是,您将无法轻松查看数据是否输入错误(即缺少值),或者系统是否删除了前导零,从而导致代价高昂的操作验证其他正确无效的邮政编码。

如果其中一个影响是业务延迟,强制用户输入正确的数据也很困难。如果用户不是很明显,那么用户通常没有耐心输入正确的数据。使用正则表达式是保证正确数据的一种方法,但是如果用户输入的值不符合并且显示错误,则可能只是完全省略该值或输入符合但不正确的值。 [使用加拿大邮政编码]的一个例子是您经常看到输入的A0A 0A0无效但符合加拿大邮政编码的正则表达式。通常情况下,这是由被迫提供邮政编码的用户输入的,但他们要么不知道它是什么,要么没有全部正确。

一个建议是验证整个条目作为一个单元,验证邮政编码与地址的其余部分相比是否正确。如果不正确,则为地址提供备用有效邮政编码将使他们更容易输入有效数据。同样,如果邮政编码对于街道地址是正确的,但街道号码不属于该邮政编码的域名,则为该邮政编码/街道组合提供备用街道号码。

答案 5 :(得分:2)

除非您有业务要求对邮政编码数据进行数学计算,否则使用INT是没有意义的。你已经过度工程了。

希望这有帮助,

比尔

答案 6 :(得分:2)

不,因为

  • 您永远不会对邮政编码进行数学运算
  • 可以包含破折号
  • 可以从0
  • 开始
  • 在标量类型的情况下,NULL值有时会被解释为零 像整数(例如,以某种方式导出数据时)
  • 邮政编码,即使是一个数字,也是一个区域的名称, 这意味着这是一个名称,而不是任何数字的数量

答案 7 :(得分:1)

邮政编码实际上是一个编码的命名空间,如果您考虑它。传统上是数字,但也是连字符和大写字母:

“10022-SHOE”

http://www.saksfifthavenue.com/main/10022-shoe.jsp

实际上,很多业务应用程序都不需要支持这种边缘情况,即使它是有效的。

答案 8 :(得分:0)

整数很好,但它只适用于美国,这就是大多数人不这样做的原因。通常我只使用varchar(20)左右。对任何语言环境来说都可能有点过分。

答案 9 :(得分:0)

如果您要使用美国Zips的整数,您可能希望将前导部分乘以10,000并添加+4。数据库中的编码与输入验证无关。您始终可以要求输入有效或无效,但存储是您认为您的要求或USPS将发生变化的程度。 (提示:您的要求更改。)

答案 10 :(得分:0)

learned recently在Ruby中你想要避免这种情况的一个原因是因为有一些邮政编码以前导零开头,如果以整数形式存储 - 将自动转换为八进制。

来自the docs

  

您可以使用特殊前缀以十进制,十六进制,八进制或二进制格式写入数字。对于十进制数字,使用前缀0d,对于十六进制数字,使用前缀0x,对于八进制数字,使用前缀0或0o ...