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
。
该类型的输入格式是地址/y
,其中地址
是一个 IPv4 或者 IPv6 地址,y
是网络掩码的位数。如果/y
部分缺失, 则网络掩码对 IPv4 而言是 32,对 IPv6 而言是 128,所以该值表示只有一台主机。在显示时,如果/y
部分指定一个单台主机,它将不会被显示出来。
cidr
cidr
类型保存一个 IPv4 或 IPv6 网络地址声明。其输入和输出遵循无类的互联网域路由(Classless Internet Domain Routing)习惯。声明一个网络的格式是地址/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 |
::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 Std 802-2001 指定第二种展示的形式(带有连字符)作为MAC地址的标准形式,并且指定第一种形式(带有分号)作为位翻转的记号,因此 08-00-2b-01-02-03 = 01:00:4D:08:04:0C。这种习惯目前已经被广泛地忽略,并且它只与废弃的网络协议(如令牌环)相关。PostgreSQL 没有对位翻转做任何规定,并且所有可接受的格式都使用标准的LSB顺序。
剩下的五种输入格式不属于任何标准。
macaddr8
macaddr8
类型存储EUI-64格式的MAC地址,
例如从以太网卡硬件地址中得知(尽管MAC地址也用于其他目的)。
这种类型可以接受6和8字节长度的MAC地址,并以8字节长度格式存储它们。
以6字节格式给出的MAC地址将以8字节长度格式存储,
第4和第5字节分别设置为FF和FE。
请注意,IPv6使用经过修改的EUI-64格式,其中第7位应该在从EUI-48转换后设置为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)