这是一个老问题的具体实例:如何在 SQL 数据库中存储“数字”(例如电话号码、IP 地址、社会保险号码)?
背景:在瑞典,个人身份证号(“personnummer”)非常普遍:您在与政府、银行、您的雇主等沟通时使用它们。在瑞典出生的人在出生时就被分配了它们。我的移民朋友们在获得个人号码并最终获得借记卡并开始寻找工作之前的几周内感叹黑暗。
我的组织需要存储我们成员的 personnummer。为此,我们有一个 SQL 数据库。我应该如何存储数据?
来自维基百科,关于personnummer的格式:
个人身份证号由 10 位数字和一个连字符组成。前六个对应于人的生日,格式为 YYMMDD。它们后跟一个连字符。100 岁以上的人用加号代替连字符。第七至第九是序列号。第九个奇数分配给男性,第九个偶数分配给女性。一些县当局,如斯德哥尔摩和一些银行,已经开始使用 12 位数字来允许 YYYYMMDD。这种格式也用于一些瑞典身份证[需要澄清]和瑞典欧洲健康保险卡,但不适用于国家签发的身份证件。
第十位是校验和,是在 1967 年系统计算机化时引入的。
因此,对于今年出生的人来说,personnummer 可能是“120101-3842”。由于 Y2K,这通常也被格式化为“20120101-3842”,并且“用加号替换连字符”并不为人所知。
在数据库列中,我想我可以:
- 将其存储为
VARCHAR
,格式为“120101-3842”、“20120101-3842”或“201201013842”(通过获取 YYYYMMDD 格式中多余的连字符来减少字节)。 - 将完整存储
YYYYMMDDXXXX
为INTEGER
,对于 32 位来说太大了,但在 64 位中没有问题。
在这种情况下,前导零不会有任何问题,并且使用 VARCHAR 几乎是两倍大小。与 IP 地址不同,将此数字存储为 INTEGER 不会使人更难阅读(即“127.0.0.1”与 相比2130706433
)。
我很欣赏专栏的“严格性”,INTEGER
但也觉得这可能会遇到看不见的问题。
编辑:我们确实需要使用校验和等来验证此输入,这需要对单个数字进行数学运算(乘法、求和等)。由于数字并不是真正的......呃......数量的一部分,而是十进制格式,因此将其视为 varchar 可能是有意义的。