56

乍一看,在数据库表中存储邮政编码有两种基本选择:

  1. 文本(可能是最常见的),即char(5)varchar(9)支持 +4 扩展
  2. 数字,即 32 位整数

如果我们假设没有国际问题,两者都将满足数据的要求。过去我们通常只是走文本路线,但我想知道是否有人反其道而行之?简单比较一下,整数方法看起来有两个明显的优点:

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

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

是否有任何不鼓励将int其用作仅限美国的邮政编码的数据类型?

4

12 回答 12

133

数字邮政编码——在某种程度上——具有误导性。

数字应该意味着数字。邮政编码不加减或参与任何数字运算。12309 - 12345 不计算从斯克内克塔迪市中心到我附近的距离。

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

由于邮政编码不是数字——它们只是碰巧用受限制的字母编码——我建议避免使用数字字段。节省 1 个字节并不值得。我认为那个意义比字节更重要。


编辑.

“至于前导零……”是我的观点。数字没有前导零。邮政编码上有意义的前导零的存在再次证明它们不是数字。

于 2009-05-21T15:15:57.343 回答
25

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

于 2009-05-21T15:12:29.567 回答
18

使用带有验证的字符串。邮政编码可以以 0 开头,因此数字不是合适的类型。此外,这也适用于国际邮政编码(例如 UK,最多 8 个字符)。在邮政编码成为瓶颈的不太可能的情况下,您可以将其限制为 10 个字符,但首先检查您的目标格式

以下是英国、美国和加拿大的验证正则表达式。


是的,您可以填充以获取前导零。但是,从理论上讲,您会丢弃可能在出现错误时有所帮助的信息。如果有人在数据库中找到 1235,那是原来的 01235,还是漏掉了另一个数字?

最佳实践表明你应该说出你的意思。邮政编码是一个代码,而不是一个数字。你要加/减/乘/除邮政编码吗?从实际的角度来看,排除加长拉链更为重要。

于 2009-05-21T15:12:50.407 回答
9

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

编辑:还应注意,如果您不打算在字段上进行数值计算,则不应使用数值数据类型。从您添加或减去它的意义上说,邮政编码不是一个数字。它只是一个通常由数字组成的字符串,因此您应该避免使用数字数据类型。

于 2009-05-21T15:14:28.873 回答
7

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

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

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

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

于 2009-05-21T15:54:19.607 回答
5

没有为什么

  • 你永远不会在邮政编码上做数学函数
  • 可以包含破折号
  • 可以从 0 开始
  • 在整数等标量类型的情况下,NULL 值有时被解释为零(例如,当您以某种方式导出数据时)
  • 邮政编码,即使它是一个数字,也是一个区域的名称,这意味着这是一个名称,而不是任何事物的数字数量
于 2016-03-21T18:54:18.757 回答
2

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

希望这可以帮助,

账单

于 2009-05-21T16:10:02.570 回答
1

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

“10022-鞋”

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

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

于 2010-05-08T20:11:32.313 回答
0

整数很好,但它只在美国有效,这就是为什么大多数人不这样做。通常我只使用 varchar(20) 左右。可能对任何语言环境都过分了。

于 2009-05-21T15:14:18.000 回答
0

如果要对美国邮政编码使用整数,则需要将前导部分乘以 10,000 并加上 +4。数据库中的编码与输入验证无关。您始终可以要求输入是否有效,但存储取决于您认为您的要求或 USPS 会发生多少变化。(提示:你的要求改变。)

于 2010-01-13T09:14:38.527 回答
0

最近了解到,在 Ruby 中,您希望避免这种情况的一个原因是,有些邮政编码以前导零开头,如果以整数形式存储,它们会自动转换为八进制。

文档

您可以使用特殊前缀来写入十进制、十六进制、八进制或二进制格式的数字。十进制数使用前缀 0d,十六进制数使用前缀 0x,八进制数使用前缀 0 或 0o...</p>

于 2018-02-24T16:48:54.873 回答
0

我认为 int 数据类型中的邮政编码会影响 ML 模型。可能,代码可以在数据中创建异常值以进行计算

于 2022-03-04T12:15:37.260 回答