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 网络规格。输入和输出格式遵循无类别域间路由约定。用于指定网络的格式为 address/y
,其中 address
是用 IPv4 或 IPv6 地址表示的网络的最低地址,而 y
是 netmask 中的位数。如果省略 y
,则使用旧类网络编号系统的假设进行计算,但它至少要足够大以涵盖输入中所写的全部八位组。指定将位设为 netmask 右侧的网络地址是错误的。
表 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
接受 netmask 右侧具有非零位的数值,而 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 位设置为 1。提供 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)