身份证件编号数据类型:护照号为何不能用整数
在 SQL 数据库中选择存储护照号的合适数据类型,这个简单问题就把开发者分成两派:一派注重数据语义,一派死记硬背。选 INTEGER 而非 VARCHAR 会丢失前导零,导致身份识别失效,这在处理数百万用户的系统中至关重要。本文基于数据的本质而非表象,剖析数据库模式设计的核心原则。
数据语义 vs. 表象
大多数开发者在面试中看到护照号是数字时,本能地选择数值类型如 INTEGER 或 BIGINT。这是典型的表面分析错误。关键问题不是数据由什么组成,而是如何使用。你从不对护照系列号或编号做算术运算——只做相等比较、搜索和传输。这些是标识符,不是数量。所以正确选择是字符串类型:系列号用 CHAR(4),编号用 CHAR(6),或合并用 CHAR(10)。用 INTEGER 存储会不可逆地丢掉前导零:0306 变成 306,使证件失效,且无错误日志。
错误选择的现实后果
选错数据类型不是理论问题——生产环境经常中招。比如一个停车许可服务中,护照字段设为 NUMBER 时悄无声息地截断了前导零,导致数据库记录与纸质证件不匹配。这漏过了代码审查和测试,直到遇到系列号以零开头的用户。在俄罗斯,数百万此类护照放大问题规模。优化论点如节省空间或索引速度站不住脚:
- CHAR(4) 对于单字节数字占用 4 字节,与 INTEGER 相同。
- VARCHAR 索引效率为 O(log n),与数值型相当,固定字符串差异微乎其微。
字节节省不值得数据丢失风险。
该规则适用于其他标识符
“不动数学运算,就不是数字”的规则适用于俄罗斯及全球系统的许多 ID。关键示例:
- SNILS(11 位数字,XXX-XXX-XXX XX 格式):剥离连字符后存为 VARCHAR(14) 或 CHAR(11),而非 BIGINT。
- 个人纳税人识别号(12 位数字):01–09 地区可能以零开头,必须用 VARCHAR(12)。
- 电话号码:仅用 VARCHAR(20),保留国际格式的 '+'。
- 邮政编码:CHAR(6),因为国际编码可能含字母。
- 银行账户(20 位数字):CHAR(20),数值型无法处理此长度否则溢出。
字符串类型确保灵活性,防止格式变更导致数据丢失。
关键要点
- 语义优先:数据类型基于操作而非外观。
- 前导零重要:数值型会剥离,导致数百万记录 ID 失效。
- 优化其次:别为字节节省或微秒换取坏数据。
- 通用原则:涵盖 SNILS、纳税人识别号、电话等。
- 审视你的模式:检查现有数据库隐藏风险。
如何选择正确数据类型
优秀工程师设计数据库字段时问三个问题:
- 语义是什么?(ID、数量、文本?)
- 操作有哪些?(比较、搜索、计算?)
- 业务规则是什么?(格式、长度、字符?)
答案决定选择:ID 用字符串,数量用数值。这区分问题解决与复制粘贴编码,早早扼杀昂贵 bug。
俄罗斯身份证件数据类型
| 数据 | 格式 | 正确类型 | 常见错误 | 错误影响 |
|------|--------|------------|----------------|--------------|
| 护照系列 | 4 位数字 | CHAR(4) | INTEGER | 前导零丢失,证件失效 |
| 护照编号 | 6 位数字 | CHAR(6) | INTEGER | 零截断,ID 破坏 |
| 完整护照 | 10 位数字 | CHAR(10) | BIGINT | 多达两个前导零丢失 |
| SNILS | 11 位数字 | CHAR(11) | BIGINT | 01–09 代码截断 |
| 个人纳税人识别号 | 12 位数字 | CHAR(12) | BIGINT | 01–09 数字丢失 |
| 电话 | +7... | VARCHAR(20) | BIGINT | 无法存 '+',无国际支持 |
| 邮政编码 | 6 位数字 | CHAR(6) | INTEGER | 无字母国际编码支持 |
| 银行账户 | 20 位数字 | CHAR(20) | 无合适 INT | 溢出,财务风险 |
此表是你的模式设计和审计速查表。
— Editorial Team
暂无评论。