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,那么掩码部分用旧的有类的网络编号系统进行计算,除非它至少大到足以包括写在输入中的所有字节。声明一个在其指定的掩码右边置了位的网络地址会导致错误。
表 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 vs. 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地址的第二种形式(带连字符)作为规范形式, 并指定第一种形式(带冒号)用于位反转、最高位在前的表示法,因此 08-00-2b-01-02-03 = 10:00:D4:80:40:C0。这种约定现在被广泛 忽略,仅适用于过时的网络协议(如Token Ring)。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进制数(字节边界上)对构成的输入(可以由':'、'-'或者'.'统一地分隔)都会被接受。16进制数的数量必须是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的大小写形式都被接受。输出总是以上面显示的第一种形式。
上述的后六种输入格式不属于任何标准。
要将传统的48位EUI-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)