如果存储少于 1 百万条记录,并且高性能不是问题,请使用 varchar(20)/char(20) 否则我发现即使存储 1 亿部全球商务电话或个人电话,int 也是最好的。原因:更小的键 -> 更高的读/写速度,格式化也可以允许重复。
char(20) 中的 1 个电话 = 20 字节 vs 8 字节bigint
(或int
本地电话 10 字节 vs 4 字节,最多 9 位),更少的条目可以进入索引块 => 更多块 => 更多搜索,请参阅此了解更多信息(为 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 哈希码。如果存储E164手机,bigint 是最佳选择。