在数据库中是否存储标准化电话号码的标准?
在数据库字段中存储电话号码的好数据结构是什么? 我正在寻找一些足够灵活的东西来处理国际号码,并且还能够有效地查询号码的各个部分。
编辑:只是为了澄清用例在这里:我目前存储数字在一个单一的varchar字段,我离开他们就像客户input他们。 然后,当代码需要这个数字的时候,我把它归一化。 问题是,如果我想查询几百万行查找匹配的电话号码,它涉及一个函数,如
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
这是非常低效的。 另外,查询区域代码的查询变得非常棘手,因为它只是一个单独的varchar字段。
[编辑]
人们在这里提出了很多好的build议,谢谢! 作为一个更新,这里是我现在正在做的:我仍然存储数字完全一样,他们在一个varchar字段,而不是正常化的事情在查询时,我有一个触发器,做所有的工作,因为logging插入或更新。 因此,我需要查询任何部分的ints或bigint,并对这些字段进行索引以使查询运行得更快。
首先,超出国家的法典,没有真正的标准。 关于你能做的最好的事情是通过国家代码来识别一个特定的电话号码属于哪个国家,并根据该国的格式来处理其余的号码。
但是,通常情况下,电话设备等都是标准化的,所以您几乎总是可以将给定的电话号码分配到以下组件中
- C国家代码1-10个数字(现在4个或更less,但可能会改变)
- 地区代码(省/州/地区)代码0-10位数字(实际上可能需要区域字段和区域字段,而不是一个地区代码)
- E交换(前缀或交换机)代码0-10位数
- L线路号码1-10位
使用这种方法,您可以将数字分开,例如,您可以find可能彼此接近的人,因为他们具有相同的国家,地区和交换代码。 随着手机不再是你可以依靠的东西。
而且,每个国家内部都有不同的标准。 您可以在美国永远依赖(AAA)EEE-LLLL,但在另一个国家,您可以在城市(AAA)EE-LLL进行交易,并且只需在农村地区(AAA)LLLL进行线路号码。 您必须从某种forms的树顶部开始,并根据您的信息进行格式化。 例如,国家/地区代码0对于其余的号码已知格式,但对于国家/地区代码5432,您可能需要检查区号,然后才能了解其余的号码。
您也可能想要处理vanity
号码,例如(800) Lucky-Guy
,它需要承认,如果是美国号码,则数字太多(您可能需要充分的代表作广告或其他用途),而在美国的字母映射的数字不同于德国。
您也可以将整个号码另存为一个文本字段(带有国际化),以便稍后返回,并在事物发生变化时重新parsing数字,或作为备份,以防某人提交不良方法来parsing特定国家/地区的格式并丢失信息。
亲吻 – 我厌倦了很多美国的网站。 他们有一些巧妙的书面代码来validation邮政编码和电话号码。 当我input我完全有效的挪威联系信息时,我发现它经常被拒绝。
留下一个string,除非你有一些更高级的特定需求。
E.164上的Wikipedia页面应该告诉你一切你需要知道的东西。
这是我的build议结构,我会很感激反馈:
电话数据库字段应该是以下格式的varchar(42):
CountryCode – Number x Extension
例如,在美国,我们可以有:
1-2125551234×1234
这将代表美国号码(国家代码1),地区代码/号码(212)555 1234和分机号码1234。
用短划线将国家代码分开,使正在阅读数据的人清楚了国家代码。 这不是严格必要的,因为国家代码是“ 前缀代码 ”(您可以从左到右阅读它们,您将始终能够明确地确定国家/地区)。 但是,由于国家/地区代码长短不一(目前在1到4个字符之间),除非您使用某种分隔符,否则无法一目了然地查看国家/地区代码。
我用一个“x”来分隔扩展名,因为如果不是的话,很多情况下不可能找出数字是哪一个,哪一个是扩展名。
通过这种方式,您可以将整个号码(包括国家/地区代码和扩展名)存储在单个数据库字段中,然后您可以使用它加速查询速度,而无需像以前那样痛苦地join用户定义的函数。
为什么我select一个varchar(42)? 那么,首先,国际电话号码将是不同的长度,因此“var”。 我存储了一个破折号和一个“x”,这样就解释了“char”,无论如何,你将不会对电话号码进行整数运算(我猜),所以尝试使用数字types没什么意义。 至于42的长度,我根据亚当·戴维斯的答案使用了所有字段的最大可能长度,并为短划线和“x”添加了2。
查阅E.164。 基本上,您将电话号码存储为以国家/地区前缀和可选pbx后缀开头的代码。 显示是一个本地化问题。 validation也可以完成,但这也是一个本地化问题(基于国家前缀)。
例如,+ 12125551212 + 202将在en_US区域设置中格式化为(212)555-1212 x202。 它在en_GB
或de_DE
中将具有不同的格式。
关于ITU-T E.164有相当多的信息,但是相当神秘。
我个人喜欢存储标准化的varchar电话号码的想法(例如9991234567),当然,在显示电话号码时要格式化该电话号码。
这样,数据库中的所有数据都是“干净的”,而且没有格式化
也许存储电话号码部分在不同的列,允许空白或空条目?
好的,根据这个页面上的信息,这里是一个国际电话号码validation器的开始:
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
我认为自由文本(也许varchar(25))是最广泛使用的标准。 这将允许任何格式,国内或国际。
我想主要的驱动因素可能是你究竟在查询这些数字以及你在做什么。
我发现大多数网页表单都正确地允许国家代码,地区代码,然后剩余的7位数字,但几乎总是忘记允许input一个扩展名。 这几乎总是让我生气,因为在工作中我们没有接待员,而我的分机号码是需要接触到我的。
我发现大多数网页表单都正确地允许国家代码,地区代码,然后剩余的7位数字,但几乎总是忘记允许input一个扩展名。 这几乎总是让我生气,因为在工作中我们没有接待员,而我的分机号码是需要接触到我的。
我将不得不检查,但我认为我们的数据库模式是相似的。 我们持有国家代码(可能默认为美国,不确定),区号,7位数字和扩展名。
如何存储一个显示电话号码的用户友好版本的自由文本列,然后是一个标准化的版本,删除空格,括号和扩展“+”。 例如:
用户友好: +44(0)181 4642542
规范化: 00441814642542
我会去一个自由文本字段和包含纯数字版本的电话号码的字段。 我会将电话号码的表示留给用户,并使用规范化的字段专门用于基于TAPI的应用程序中的电话号码比较,或者尝试查找电话号码簿中的双项时。 当然,这不会给用户提供一个入口scheme,增加智能,如国家代码(如有必要),地区代码,基数和扩展名等单独的字段。
你从哪里得到电话号码? 如果你从电话networking的一部分得到他们,你会得到一串数字和数字types和计划,例如
441234567890types/计划0x11(表示国际E.164)
在大多数情况下,最好的办法是将所有这些存储起来,然后进行标准化显示,但如果要将它们用作唯一键或类似标记,则存储标准化数字可能会很有用。
用户友好:+44(0)181 464 2542标准化:00441814642542
(0)在国际格式中无效。 参见ITU-T E.123标准。
美国读者使用“正常化”格式,因为他们使用011来进行国际访问。
我已经使用了3种不同的方式来存储电话号码,具体取决于使用要求。
- 如果该号码只是为了人工检索而被存储,并且不会被用于按照用户input的那样来存储在stringtypes字段中。
- 如果要search该字段,则会删除任何多余的字符,例如+,空格和括号等,其余的字符将存储在stringtypes字段中。
- 最后,如果电话号码将被计算机/电话应用使用,则在这种情况下,需要input并存储作为系统可用的有效电话号码,这个选项当然是最难编码的对于。
格式化数字的标准是e.164 ,您应该始终以这种格式存储数字。 您不应该在电话号码的同一字段中允许分机号码,这些号码应该单独存储。 至于数字和字母数字,这取决于你将要用这些数据做什么。