PostgreSQL 提供了用于存储 IPv4、IPv6 和 MAC 地址的数据类型,如 表 8.21 所示。最好使用这些类型而不是普通文本类型来存储网络地址,因为这些类型提供了输入错误检查以及专门的运算符和函数(参见 第 9.12 节)。
表 8.21. 网络地址类型
| 名称 | 存储大小 | 描述 |
|---|---|---|
cidr |
7 或 19 字节 | IPv4 和 IPv6 网络 |
inet |
7 或 19 字节 | IPv4 和 IPv6 主机和网络 |
macaddr |
6 字节 | MAC 地址 |
macaddr8 |
8 字节 | MAC 地址 (EUI-64 格式) |
在对 inet 或 cidr 数据类型进行排序时,IPv4 地址始终排在 IPv6 地址之前,包括封装或映射到 IPv6 地址的 IPv4 地址,例如 ::10.2.3.4 或 ::ffff:10.4.3.2。
inet #inet 类型在一个字段中包含一个 IPv4 或 IPv6 主机地址,以及可选的子网。子网由主机地址中存在的网络地址位数(“网络掩码”)表示。如果网络掩码是 32 并且地址是 IPv4,那么该值仅表示一个单独的主机,而不表示子网。在 IPv6 中,地址长度为 128 位,因此 128 位指定一个唯一的主机地址。请注意,如果您只想接受网络,则应使用 cidr 类型而不是 inet。
此类型的输入格式为 address/y,其中 address 是 IPv4 或 IPv6 地址,y 是网络掩码中的位数。如果省略 /y 部分,则对于 IPv4,网络掩码假定为 32;对于 IPv6,假定为 128,因此该值仅表示一个单独的主机。显示时,如果网络掩码指定的是单个主机,则会隐藏 /y 部分。
cidr #cidr 类型包含一个 IPv4 或 IPv6 网络规范。输入和输出格式遵循无类别域间路由(Classless Internet Domain Routing)约定。指定网络的格式为 address/y,其中 address 是网络的最低地址,表示为 IPv4 或 IPv6 地址,y 是网络掩码中的位数。如果省略 y,则使用旧的类别网络编号系统的假设进行计算,但它至少会足够大以包含输入中写出的所有字节。指定一个网络地址,该地址在指定的网络掩码右侧有设置为 1 的比特位是错误的。
表 8.22 显示了一些示例。
表 8.22. cidr 类型输入示例
cidr 输入 |
cidr 输出 |
|
|---|---|---|
| 192.168.100.128/25 | 192.168.100.128/25 | 192.168.100.128/25 |
| 192.168/24 | 192.168.0.0/24 | 192.168.0/24 |
| 192.168/25 | 192.168.0.0/25 | 192.168.0.0/25 |
| 192.168.1 | 192.168.1.0/24 | 192.168.1/24 |
| 192.168 | 192.168.0.0/24 | 192.168.0/24 |
| 128.1 | 128.1.0.0/16 | 128.1/16 |
| 128 | 128.0.0.0/16 | 128.0/16 |
| 128.1.2 | 128.1.2.0/24 | 128.1.2/24 |
| 10.1.2 | 10.1.2.0/24 | 10.1.2/24 |
| 10.1 | 10.1.0.0/16 | 10.1/16 |
| 10 | 10.0.0.0/8 | 10/8 |
| 10.1.2.3/32 | 10.1.2.3/32 | 10.1.2.3/32 |
| 2001:4f8:3:ba::/64 | 2001:4f8:3:ba::/64 | 2001:4f8:3:ba/64 |
| 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 | 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 | 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 |
| ::ffff:1.2.3.0/120 | ::ffff:1.2.3.0/120 | ::ffff:1.2.3/120 |
| ::ffff:1.2.3.0/128 | ::ffff:1.2.3.0/128 | ::ffff:1.2.3.0/128 |
inet 与 cidr #inet 和 cidr 数据类型之间的主要区别在于 inet 接受网络掩码右侧存在非零位的数值,而 cidr 则不行。例如,192.168.0.1/24 对于 inet 是有效的,但对于 cidr 则无效。
如果您不喜欢 inet 或 cidr 值的输出格式,请尝试使用 host、text 和 abbrev 函数。
macaddr #macaddr 类型存储 MAC 地址,例如从以太网卡硬件地址得知(尽管 MAC 地址也用于其他目的)。接受以下格式的输入:
'08:00:2b:01:02:03' |
'08-00-2b-01-02-03' |
'08002b:010203' |
'08002b-010203' |
'0800.2b01.0203' |
'0800-2b01-0203' |
'08002b010203' |
这些示例都指定了同一个地址。对于数字 a 到 f,接受大写和小写。输出始终是显示的第一个格式。
IEEE 标准 802-2001 将显示的第二种格式(带连字符)指定为 MAC 地址的标准格式,并将第一种格式(带冒号)指定为与位反转、MSB 优先的表示法一起使用,因此 08-00-2b-01-02-03 = 10:00:D4:80:40:C0。如今,这种约定已被广泛忽略,并且只与过时的网络协议(如令牌环)相关。PostgreSQL 不提供位反转的机制;所有接受的格式都使用标准的 LSB 顺序。
其余五种输入格式不属于任何标准。
macaddr8 #macaddr8 类型以 EUI-64 格式存储 MAC 地址,例如从以太网卡硬件地址得知(尽管 MAC 地址也用于其他目的)。此类型可以接受 6 字节和 8 字节长度的 MAC 地址,并以 8 字节长度格式存储。以 6 字节格式提供的 MAC 地址将以 8 字节长度格式存储,其中第 4 个和第 5 个字节分别设置为 FF 和 FE。请注意,IPv6 使用修改后的 EUI-64 格式,其中从 EUI-48 转换后,第 7 位应设置为一。函数 macaddr8_set7bit 用于进行此更改。总的来说,任何由十六进制数字对(在字节边界上)组成的输入,可以选择性地用 ':'、'-' 或 '.' 中的一个一致分隔,都是可接受的。十六进制数字的数量必须是 16(8 字节)或 12(6 字节)。忽略前导和尾随空格。以下是可接受的输入格式示例:
'08:00:2b:01:02:03:04:05' |
'08-00-2b-01-02-03-04-05' |
'08002b:0102030405' |
'08002b-0102030405' |
'0800.2b01.0203.0405' |
'0800-2b01-0203-0405' |
'08002b01:02030405' |
'08002b0102030405' |
这些示例都指定了同一个地址。对于数字 a 到 f,接受大写和小写。输出始终是显示的第一个格式。
上面显示的最后六种输入格式不属于任何标准。
要将 EUI-48 格式的传统 48 位 MAC 地址转换为修改后的 EUI-64 格式,以便作为 IPv6 地址的主机部分包含进来,请使用 macaddr8_set7bit,如下所示:
SELECT macaddr8_set7bit('08:00:2b:01:02:03');
macaddr8_set7bit
-------------------------
0a:00:2b:ff:fe:01:02:03
(1 row)