【问题标题】:mysql datatype for telephone number and address电话号码和地址的mysql数据类型
【发布时间】:2010-12-23 04:58:23
【问题描述】:

我想在表格中输入电话号码,包括国家代码、分机号

create table if not exists employee(    `   
      country_code_tel   int(11),
      tel_number         int(10),
      extension          int(10),
      mobile             bigint(20)
);

如果tel_number大于15位,我可以使用哪种数据类型,我最好使用Bigint(20)

create table address(
      address           varchar(255),  
      city              varchar(255),
      country           varchar(255),
      post_code         int(11)
);

例如,如果我有加拿大的国家代码,我可以使用 +2 或 002。哪个更适合处理?

感谢您的建议。

【问题讨论】:

    标签: mysql types phone-number street-address


    【解决方案1】:

    好吧,我个人不使用数字数据类型来存储电话号码或相关信息。

    你如何存储一个数字,比如 001234567?它将以 1234567 结束,失去前导零。

    当然,您可以随时将其向上填充,但前提是您确切知道该数字应该是多少位数。

    这并不能回答您的整个帖子,
    只是我的 2 美分

    【讨论】:

    【解决方案2】:

    实际上,您可以将 varchar 用作电话号码。您不需要 int,因为您不会对数字执行算术运算。

    【讨论】:

    • @Vincent,但如果我想使用验证数字格式,我想我必须使用 int。其实这是我第一次做“真正的应用”,所以我想从真正的项目中得到你的建议。
    • @garcon1986:在提交到数据库之前,必须在您的应用程序上完成验证(不是“身份验证”)。您可能更喜欢编写带有验证 PL 过程的 SQL 触发器以驻留在数据库中 - 这会更难,但如果您的数据库数据将被不同人用不同编程语言编写的前端应用程序访问,那么这是要走的路 - ,但您不应该依赖数据库数据类型进行验证
    • @garcon1986 使用 varchar 进行验证仍然比使用 int 更容易。我知道的每个实际项目都使用 varchar 而不是 int 来表示电话字段。甚至验证库也需要字符。
    • @非常感谢,文森特。我很抱歉首先误解了这两个概念。我会尝试在电话号码中使用“varchar”类型进行验证。
    • @garcon1986 完全没有问题。无需道歉...这就是该网站存在的原因
    【解决方案3】:

    将它们存储为电话号码的两个字段 - 一个“号码”和一个“掩码”为 TinyText 类型不需要超过 255 个项目

    在我们存储文件之前,我们会解析电话号码以获取已使用的格式并创建掩码,然后我们仅将数字存储为数字,例如

    输入:(0123) 456 7890
    号码:01234567890
    面具:(nnnn)_nnn_nnnn

    理论上,这允许我们在号码字段上执行比较搜索,例如获取以特定区号开头的所有电话号码,而不必担心用户是如何输入的

    【讨论】:

    • @Dan Kelly,谢谢,您为我提供了另一种方法。酷!
    • 只是好奇:为什么选择 TINYTEXT?
    • 在我们的例子中,我们希望能够将前导 0 存储在“数字”字段中,并且没有看到任何存储数据大于 255 个字符的情况。
    【解决方案4】:

    我通常将电话号码存储为 E164 格式的 BIGINT。

    E164 从不以 0 开头,前几位数字是国家代码。

    +441234567890
    +44 (0)1234 567890
    01234 567890
    

    等等。将存储为441234567890

    【讨论】:

    • 我很惊讶这个答案没有得到更多的选票——我也选择了未签名的 BIGINT。我同意 E164 从不以 0 开头,总是以我的应用程序添加的 + 开头,只包含数字,最重要的是它使用的空间比字符类型少得多。
    • 感谢您指出缺少以 0 开头的数字。我以前不知道这一点。因此,假设完整的 E.164 格式,前导零应该只是国际拨号前缀的一部分,即拨出代码,因地区而异,而不是号码本身的一部分。该前缀实际上是应用程序或使用号码的人的位置的函数,而不是号码本身,因此通常不应存储。在未来的设计中,我会考虑使用 bigint。
    【解决方案5】:

    我会使用 varchar 作为电话号码。这样您还可以存储 + 和 (),这有时会在电话号码中看到(正如您自己提到的)。而且您不必担心用完整数中的所有位。

    【讨论】:

    • @KON,谢谢,我现在更喜欢使用 varchar 作为电话号码。
    【解决方案6】:

    我不确定使用整数是否是个好主意。某些数字可能包含特殊字符(例如,# 作为扩展名的一部分),您也应该能够处理这些字符。所以我建议改用 varchars。

    【讨论】:

    • @nfechner,感谢提供案例,很实用。
    • 我们在这里使用“x”.. 999 9999 x1234
    • 有时单独存储扩展名可能是明智之举。例如,在自动语音消息应用程序中,应用程序必须知道拨打号码、等待接听电话、暂停,然后拨打分机号。换句话说,这两个部分对应用程序具有不同的含义,并且可能需要不同的代码。在我看来,使用两列处理比在一列中使用分隔符更干净。我并不是说任何一种方式是对还是错。这取决于手头的设计权衡。我只是想指出还有其他处理扩展的方法。
    【解决方案7】:

    如果存储少于 1 百万条记录,并且高性能不是问题,请使用 varchar(20)/char(20),否则我发现即使存储 1 亿部全球商务电话或个人电话,int 也是最好的.原因:更小的键 -> 更高的读/写速度,格式化也可以允许重复。

    char(20) 中的 1 个电话 = 20 字节 vs 8 字节 bigint(或本地电话 10 字节 vs 4 字节 int,最多 9 位),更少的条目可以进入索引块 => 更多块 = > 更多搜索,请参阅this 了解更多信息(为 Mysql 编写,但对于其他关系数据库应该也是如此)。

    以下是电话表的示例:

    CREATE TABLE `phoneNrs` (   
        `internationalTelNr` bigint(20) unsigned NOT NULL COMMENT 'full number, no leading 00 or +, up to 19 digits, E164 format',
        `format` varchar(40) NOT NULL COMMENT 'ex: (+NN) NNN NNN NNN, optional',
        PRIMARY KEY (`internationalTelNr`)
        )
    DEFAULT CHARSET=ascii
    DEFAULT COLLATE=ascii_bin
    

    或在插入前进行处理/拆分(2+2+4+1 = 9 个字节)

    CREATE TABLE `phoneNrs` (   
        `countryPrefix` SMALLINT unsigned NOT NULL COMMENT 'countryCode with no leading 00 or +, up to 4 digits',
        `countyPrefix` SMALLINT unsigned NOT NULL COMMENT 'countyCode with no leading 0, could be missing for short number format, up to 4 digits',
        `localTelNr` int unsigned NOT NULL COMMENT 'local number, up to 9 digits',
        `localLeadingZeros` tinyint unsigned NOT NULL COMMENT 'used to reconstruct leading 0, IF(localLeadingZeros>0;LPAD(localTelNr,localLeadingZeros+LENGTH(localTelNr),'0');localTelNr)',
        PRIMARY KEY (`countryPrefix`,`countyPrefix`,`localLeadingZeros`,`localTelNr`)  -- ordered for fast inserts
    ) 
    DEFAULT CHARSET=ascii
    DEFAULT COLLATE=ascii_bin
    ;
    

    还有“电话号码不是号码”,在我看来是相对于电话号码的类型而言的。如果我们谈论的是内部移动电话簿,那么字符串就可以了,因为用户可能希望存储GSM Hash Codes。如果存储E164 电话,bigint 是最佳选择。

    【讨论】:

      【解决方案8】:

      考虑规范化为E.164 格式。要获得全面的国际支持,您需要一个 15 位数字的 VARCHAR。

      有关电话号码本地化的更多信息,请参阅Twilio's recommendation

      【讨论】:

        【解决方案9】:

        INT(10) 不是 10 位数字,它是一个显示宽度为 10 位的整数。 MySQL 中 INT 的最大值为 2147483647(如果无符号,则为 4294967295)。

        您可以使用 BIGINT 而不是 INT 将其存储为数字。使用 BIGINT 将比 VARCHAR(10) 每行节省 3 个字节。

        分别存储“国家+地区+号码”。您可以尝试使用 VARCHAR(20),这样您就可以在需要时正确存储国际电话号码。

        【讨论】:

          【解决方案10】:

          varchar 或 text 应该是存储手机号码的最佳数据类型。

          【讨论】:

            【解决方案11】:

            您可以使用KeyPress 事件将您的输入限制为字段中的数字,然后在插入时,在您的Insert Into Table 中添加一个+ 到命令。

            轻松解决

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-13
              • 2018-04-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-09-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多