19

在我工作过的最后 3 家公司中,电话号码列的类型为 varchar(n)。原因是他们可能想要存储扩展(分机 333)。但在每种情况下,插入和更新时都会去掉“-”字符。我不明白为什么“.ext”字符可以存储,但“-”字符不行。有没有其他人看到过这个,你能想到什么解释这样做?如果您只想存储数字,那么使用 int 字段不是更好吗?相反,如果您想将数字存储为字符串/varchar,那么为什么不保留所有字符,而不用在显示时进行格式化和在写入时进行清理呢?

我也有兴趣了解在其他地方实施电话号码存储的其他方式。

4

10 回答 10

30

快速测试:你要加/减/乘/除电话号码吗?没有。与 SSN 类似,电话号码是可以包含实际号码的离散数据,因此字符串类型可能是最合适的。

于 2008-11-14T16:19:01.970 回答
12

存储电话号码的一点是前导 0。

例如:01202 8765432

在 int 列中,0 将被去除,这使得电话号码无效。

我会冒险猜测 - 被换成空格是因为它们实际上没有任何意义

例如:123-456-789 = 123 456 789 = 123456789

于 2008-11-14T16:17:22.160 回答
3

就个人而言,我不会删除任何字符,因为根据电话号码的来源,它可能意味着不同的东西。将电话号码保留为输入的确切格式,因为显然这是输入它的人习惯于查看它的方式。

于 2008-11-14T16:28:13.603 回答
1

你如何存储它并不重要,只要它是一致的。规范是去除格式化字符,但如果您需要查询这些值,您也可以单独存储国家代码、区号、交换和扩展名。同样,要求是一致的 - 否则查询它是一个 PITA。

于 2008-11-14T17:14:50.890 回答
1

我能想到不将电话号码存储为“数字”而是作为字符串存储的另一个原因是,您用来访问数据库的软件堆栈的足够部分(PHP,我正在看你)不会支持足够大的整数(本机)以能够存储一些较长和/或异国情调的电话号码。

32 位可以携带的最大数字是 4294967295。这不适用于任何俄罗斯手机号码,例如数字 4959261234。

因此,您要找到一种方法来携带超过 32 位的数字数据,这给您带来了额外的不便。尽管数据库长期以来一直支持非常大的整数,但您只需要链中的一个坏链接就可以了。就像 PHP 一样。

于 2011-07-30T17:39:00.610 回答
0

如果数据库表要驱动另一个系统(例如某种 IP 电话),则去除某些字符并允许其他字符可能会产生影响。根据所涉及的系统,将 etc.333 作为后缀可能是合法的,而开发人员可能没有考虑字符串中的“-”(是的,我猜这里......)

至于存储为 varchar 而不是 int,这对我来说只是普通的常识。如前所述,前导零可能会在 int 字段中被剥离,对 int 字段的查询可能会执行隐式数学函数(这也可以解释从文本中剥离“-”,您不想输入 555-1234 并有它存储为-679吗?)

总之,我不知道确切的推理,但可以推断出一些可能性。

于 2008-11-14T16:26:56.603 回答
0

如果我知道电话号码只会在特定区域(例如北美)内,我喜欢做的是将条目更改为 4 个字段。3 代表区号,3 代表前缀,3 代表线路,也许 5 代表分机。然后,我将这些作为 1 个字段插入,带有“-”,可能还有一个“e”来指定扩展名。当然,任何搜索也需要遵循相同的过程。这样可以确保我获得更多常规数据,甚至可以在删除 - 和扩展名后将该号码用于实际拨打电话。我也可以轻松回到原来的 4 个字段。

于 2008-11-14T17:28:23.827 回答
0

好东西!似乎主要的一点是电话号码的格式实际上并不是数据的一部分,而是来源国家的一个方面。尽管如此,通过保持数字的扩展部分不变,可能会破坏将格式与数据分离的模型。我怀疑所有国家/地区都使用相同的语法/格式来描述扩展名。此外,如果与电话系统集成是(可能的)要求,那么最好单独存储扩展并按预期构建消息。但马克也提出了一个很好的观点,如果你是一致的,那么你如何存储它可能并不重要,因为你也可以一致地查询和处理它。

感谢 Eric 提供另一个问题的链接。

于 2008-11-14T17:47:58.000 回答
0

我会选择将数字存储为字符串,并在我的显示代码中添加各种“()”和“-”。国际号码确实变得更加困难。我们通过根据国家/地区采用各种“国际化”显示格式来处理它。

于 2008-11-14T16:38:07.047 回答
0

当自动电话系统使用字段拨打电话时,它可能无法分辨应该使用哪些字符以及在拨号时应该忽略哪些字符。人们可能会看到“(”或“)”或“-”字符并知道这些被视为分隔电话号码的区号、npa 和 nxx 的分隔符。请记住,每个字符都代表一个二进制模式,除非预先编程为忽略,否则将由自动拨号器输入。考虑到这一点,最好只存储用户在手机上按下的字符的等价物,甚至更好地将各个值存储在单独的列中,这样拨号器就可以使用各个字段而无需解析字符串。

即使不使用拨号自动化,存储您将来不需要更新的内容也是一个好习惯。在字段之间添加字符比从字符串中删除字符要容易得多。

在评论使用如上所述的字符串与整数数据类型时,字符串是根据国家/地区之间的差异存储电话号码的正确方法。有一个重要的警告,尽管在聚合统计数据以报告(即多少数字或调用的总和)时,字符串的计数比整数慢得多。考虑到这一点,添加一个整数作为标识列很重要,您可以将其用于计数,而不是 varchar 或 char 字段数据类型。

于 2013-11-12T23:39:31.923 回答