网络地址类型 ================= OushuDB 提供用于存储 IPv4、IPv6 和 MAC 地址的数据类型,如\ `表 `__\ 所示。 用这些数据类型存储网络地址比用纯文本类型好,因为这些类型提供输入错误检查以及特殊的操作符和函数(见\ `第 9.12 节 `__\ ) .. container:: table :name: DATATYPE-NET-TYPES-TABLE **表 网络地址类型** .. container:: table-contents ============ ========= ====================== 名字 存储尺寸 描述 ============ ========= ====================== ``cidr`` 7或19字节 IPv4和IPv6网络 ``inet`` 7或19字节 IPv4和IPv6主机以及网络 ``macaddr`` 6字节 MAC地址 ``macaddr8`` 8 bytes 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**\ , 那么掩码部分用旧的有类的网络编号系统进行计算,否则它将至少大到足以包括写在输入中的所有字节。声明一个在其指定的掩码右边置了位的网络地址会导致错误。 `表 `__\ 展示了一些例子。 .. container:: table :name: DATATYPE-NET-CIDR-TABLE **表 ``cidr``\ 类型输入例子** .. container:: table-contents +----------------------+----------------------+----------------------+ | ``cidr``\ 输入 | ``cidr``\ 输出 | ``abbrev(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:2e | 2001:4f8:3:ba:2e | 2001:4f8:3:b | | 0:81ff:fe22:d1f1/128 | 0:81ff:fe22:d1f1/128 | a: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``\ 是无效的。 .. tip:: .. rubric:: 提示 :name: 提示 :class: title 如果你不喜欢\ ``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格式,其中从EUI-48转换过来后的第7位应该被设置为一。函数\ ``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``\ 的大小写形式都被接受。输出总是以上面显示的第一种形式。 上述的后六种输入格式不属于任何标准。 要把EUI-48格式的传统48位MAC地址转换成修改版EUI-64格式(包括在IPv6地址中作为主机部分),可以使用下面的\ ``macaddr8_set7bit``\ : .. code:: programlisting SELECT macaddr8_set7bit('08:00:2b:01:02:03'); macaddr8_set7bit ------------------------- 0a:00:2b:ff:fe:01:02:03 (1 row)