是否有用于在数据库中存储标准化电话号码的标准?

时间:2020-03-05 18:47:06  来源:igfitidea点击:

在数据库字段中存储电话号码的良好数据结构是什么?我正在寻找一种足够灵活的方式来处理国际号码,同时也希望能够有效地查询号码的各个部分。

编辑:这里只是为了阐明用例:我目前将数字存储在单个varchar字段中,并且在客户输入时将其保留。然后,当代码需要数字时,我将其标准化。问题是,如果我想查询几百万行以查找匹配的电话号码,它涉及到一个功能,例如

where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)

这是非常低效的。当查询仅是一个varchar字段时,查找区号之类的查询也会变得非常棘手。

[编辑]

人们在这里提出了很多好的建议,谢谢!作为更新,这是我现在正在做的事情:我仍然将输入的数字完全存储在varchar字段中,但是我没有在查询时对数据进行规范化,而是有一个触发器,可以在插入记录时完成所有工作或者更新。因此,对于需要查询的任何部分,我都有ints或者bigints,并且对这些字段进行了索引以使查询运行更快。

解决方案

回答

也许将电话号码部分存储在不同的列中,以允许输入空白或者空值?

回答

我认为自由文本(也许是varchar(25))是使用最广泛的标准。这将允许使用任何格式,无论是国内格式还是国际格式。

我想主要的驱动因素可能是我们查询这些数字的准确程度以及我们对它们的处理方式。

回答

吻我对美国的许多网站感到厌倦。他们编写了一些巧妙的代码来验证邮政编码和电话号码。当我输入完全有效的挪威联系信息时,我发现它经常被拒绝。

保留字符串,除非我们对某些更高级的内容有特定的需求。

回答

如何存储一个自由文本列,该列显示电话号码的用户友好版本,然后存储一个标准化版本,该版本删除空格,方括号并扩展" +"。例如:

使用者友善:+44(0)181 4642542

标准化的:00441814642542

回答

我发现大多数Web表单正确地允许输入国家代码,区号,然后是其余的7位数字,但几乎总是忘记允许输入扩展名。这几乎总是使我发脾气,因为在工作中我们没有接待员,需要我的分机才能与我联系。

回答

我个人喜欢存储标准化的varchar电话号码(例如9991234567),然后在显示时内联格式化该电话号码的想法。

这样,数据库中的所有数据都是"干净的"并且没有格式

回答

I find most web forms correctly allow for the country code, area code, then the remaining 7 digits but almost always forget to allow entry of an extension. This almost always ends up making me utter angry words, since at work we don't have a receptionist, and my ext.# is needed to reach me.

我必须检查一下,但我认为我们的数据库架构是相似的。我们拥有国家代码(不确定,可能默认为美国),区号,7位数字和扩展名。

回答

首先,除了国家/地区代码之外,没有真正的标准。最好的办法就是通过国家/地区代码识别特定电话号码属于哪个国家/地区,然后根据该国家/地区的格式处理其余的号码。

但是,通常电话设备等都是标准化的,因此我们几乎总是可以将给定的电话号码分解为以下部分

  • C国家/地区代码1到10位数字(目前为4或者更少,但可能会更改)
  • 区域代码(省/州/地区)代码0到10位数字(实际上可能需要一个区域字段和一个区域字段,而不是一个区域代码)
  • E交换(前缀或者交换)代码0-10位
  • L行号1-10位数字

使用此方法,我们可以潜在地分隔数字,例如,我们可以找到由于彼此具有相同的国家,地区和交换代码而可能彼此靠近的人。使用手机已不再是我们可以指望的东西。

此外,每个国家内部都有不同的标准。在美国,我们始终可以依赖(AAA)EEE-LLLL,但在另一个国家,我们可能在城市(AAA)EE-LLL中有交换所,而在农村地区(AAA)LLLL中则只是行号。我们将必须从某种形式的树的顶部开始,并在拥有信息时格式化它们。例如,国家/地区代码0的其余部分为已知格式,但是对于国家/地区代码5432,我们可能需要先检查区号,然后才能理解其余部分。

我们可能还需要处理"虚荣"号码,例如"(800)Lucky-Guy",该号码需要认识到,如果是美国号码,则数字太多了(出于广告或者其他目的,我们可能需要完整表示) ),在美国,字母映射到数字的方式与在德国不同。

我们可能还希望将整个数字分别存储为文本字段(国际化),以便稍后再返回并根据情况变化重新解析数字,或者作为备份,以防有人提交了错误的方法来解析特定国家/地区的格式并丢失信息。

回答

查找E.164. 基本上,我们将电话号码存储为以国家/地区前缀和可选的pbx后缀开头的代码。显示便是一个本地化问题。验证也可以完成,但这也是一个本地化问题(基于国家/地区前缀)。

例如,+ 12125551212 + 202将在en_US语言环境中格式化为(212)555-1212 x202. 它在en_GB或者de_DE中将具有不同的格式。

关于ITU-T E.164的信息很多,但它很神秘。

回答

我将使用自由文本字段和包含电话号码的纯数字版本的字段。我会将电话号码的表示形式留给用户,并使用归一化字段专门用于基于TAPI的应用程序中的电话号码比较,或者尝试在电话目录中查找重复条目时使用。

回答

当然,为用户提供一种增加智能的输入方案也无妨,例如国家代码(如有必要),区号,基本号码和扩展名的单独字段。

function validatePhone(phoneNumber) {
    var valid = true;
    var stripped = phoneNumber.replace(/[\(\)\.\-\ \+\x]/g, '');    

    if(phoneNumber == ""){
        valid = false;
    }else if (isNaN(parseInt(stripped))) {
        valid = false;
    }else if (stripped.length > 40) {
        valid = false;
    }
    return valid;
}

好的,因此,根据此页面上的信息,以下是国际电话号码验证器的开始:

回答

宽松地基于此页面上的脚本:http://www.webcheatsheet.com/javascript/form_validation.php

回答

E.164上的Wikipedia页面应告诉我们所有我们需要了解的内容。

  • 如果该数字仅用于人类检索而存储,则不会完全按照用户输入的方式用于搜索存储在字符串类型字段中的数字。
  • 如果要搜索该字段,则将删除所有多余的字符,例如+,空格和方括号等,并将剩余数字存储在字符串类型字段中。
  • 最后,如果电话号码将由计算机/电话应用程序使用,则在这种情况下,需要输入电话号码并将其存储为系统可用的有效电话号码,当然,此选项最难编码为了。

回答

根据使用需求,我使用了3种不同的方式来存储电话号码。

这是我建议的结构,感谢反馈:

电话数据库字段应为具有以下格式的varchar(42):

国家/地区代码编号x扩展名

因此,例如,在美国,我们可以:

1-2125551234x1234

这将代表具有区号/号码(212)555 1234和扩展名1234的美国号码(国家代码1)。

用破折号分隔国家/地区代码可使正在阅读数据的人清楚国家/地区代码。这不是严格必需的,因为国家/地区代码是"前缀代码"(我们可以从左到右阅读它们,并且始终可以明确确定国家/地区)。但是,由于国家/地区代码的长度是不同的(目前在1到4个字符之间),除非我们使用某种分隔符,否则我们一眼就能分辨出国家/地区代码。

我使用" x"分隔扩展名,因为否则(在许多情况下)实际上是不可能确定哪个是数字,哪个是扩展名。

这样,我们可以将完整的数字(包括国家代码和分机号)存储在一个数据库字段中,然后用于加快查询速度,而不必像到目前为止那样费心地加入用户定义的函数。

回答

为什么选择varchar(42)?好吧,首先,国际电话号码的长度会有所不同,因此是" var"。我存储一个破折号和一个" x",以便解释" char",无论如何,我们不会对电话号码进行整数运算(我想),因此尝试使用数字类型几乎没有任何意义。 。至于42的长度,我根据亚当·戴维斯(Adam Davis)的答案使用了所有字段的最大可能长度,并在破折号和'x'处加了2.

我们从哪里获得电话号码?如果要从电话网络中获取它们,则会得到一串数字以及一个数字类型和计划,例如

441234567890类型/计划0x11(表示国际E.164)

段落数量不匹配