日期:2026-07-11
标签:#面试 #八股 #后端 #数据库 #场景题
一句话答案
若只支持 IPv4 可存无符号 32 位整数;兼容 IPv4 和 IPv6 时优先存 16 字节二进制,并在应用边界使用标准转换函数。
面试口语版
不建议默认用可变字符串直接存 IP。IPv4 本质是 32 位,可使用 MySQL INT UNSIGNED;如果系统需要兼容 IPv6,统一使用 VARBINARY(16) 或 BINARY(16) 更节省空间,也更适合索引和范围查询。MySQL 可用 INET6_ATON 把文本转二进制,用 INET6_NTOA 转回展示。选择定长还是变长取决于是否统一保存为 16 字节表示以及数据库约定。
方案对比
| 类型 | 空间 | IPv6 | 查询与索引 |
|---|---|---|---|
VARCHAR(39) | 较大 | 支持 | 文本格式不统一,范围查询不便 |
INT UNSIGNED | 4 字节 | 不支持 | IPv4 高效 |
VARBINARY(16) | 4/16 字节 | 支持 | 紧凑,适合索引与网段判断 |
关键细节
- IPv6 文本存在压缩和大小写等多种等价形式,直接按字符串比较不可靠。
- Java 中不要用有符号
int的正负语义表示 IPv4 数值,可使用long或字节数组。 - 如果需要 CIDR 网段检索,应保存二进制地址、前缀长度或额外维护范围起止值。
- 日志展示和数据库存储可以采用不同格式。
面试官追问
- IPv4 如何转换成 32 位整数?
- 如何判断一个 IP 是否属于某个 CIDR?
- IPv4-mapped IPv6 地址如何处理?
面试官追问参考答案
1. IPv4 如何转换成 32 位整数?
将四段 a.b.c.d 转为 (a<<24)|(b<<16)|(c<<8)|d。Java 应用 long 承载无符号结果并对每段校验 0–255;反向则依次无符号右移并与 0xff。
2. 如何判断一个 IP 是否属于某个 CIDR?
把 IP 和网段地址转二进制,根据前缀长度生成掩码,判断 (ip & mask) == (network & mask)。IPv6 同理使用 128 位字节数组;数据库查询可保存范围起止值,或使用数据库原生网络类型与运算符。
3. IPv4-mapped IPv6 地址如何处理?
它通常形如 ::ffff:a.b.c.d。系统应在入口规定统一规范:要么保留 16 字节映射形式,要么识别后规范为 4 字节 IPv4;比较、唯一约束和网段规则必须使用同一种表示,避免同一地址存两份。
学习清单
- 掌握 IPv4 的 32 位表示和 IPv6 的 128 位表示。
- 了解 MySQL
INET6_ATON/INET6_NTOA。