购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.10 网络地址类型

PostgreSQL为IPv4、IPv6以及以太网MAC地址都提供了特有的类型,使用这些类型存储IP地址、MAC地址相对于用字符串存储这些类型来说,不容易产生歧义,同时提供了相应的函数让IP地址的运算更方便,本节将详细讲解这些类型的使用方法。

5.10.1 网络地址类型概况

PostgreSQL提供了专门的数据类型来存储IPv4、IPv6和MAC地址。这比使用字符串效果更好一些,因为使用这些类型有助于更好地做检测。涉及的类型见表5-25。

表5-25 网络地址类型列表

5.10.2 inet与cidr类型

inet和cidr类型都可以用于存储一个IPv4或IPv6的地址,示例如下:


osdba=# select '192.168.1.100'::inet;
      inet      
---------------
  192.168.1.100
(1 row)

osdba=# select '192.168.1.100'::cidr;
        cidr       
------------------
  192.168.1.100/32
(1 row)

这两种类型输入IPv4地址的格式相同,具体如下:


x.x.x.x/masklen

其掩码可以省略,格式如下:


x.x.x.x

注意,掩码的长度都是用一个数字表示的,不能使用如下格式:


osdba=# select '198.168.1.100/255.255.255.0'::cidr;
ERROR:  invalid input syntax for type cidr: "198.168.1.100/255.255.255.0"
LINE 1: select '198.168.1.100/255.255.255.0'::cidr;
               ^
osdba=# select '198.168.1.100 255.255.255.0'::inet;
ERROR:  invalid input syntax for type inet: "198.168.1.100 255.255.255.0"
LINE 1: select '198.168.1.100 255.255.255.0'::inet;
               ^

IPv6地址的输入格式如下:


ipv6_addr/masklen

其中ipv6_addr可以使用标准的IPv6地址表示方式,即分为8组,每组为4个十六进制数的形式,具体格式如下:


DA70:0000:0000:0000:ABCD:0000:00F7:0003

如果觉得上面的表示方法太长,还可以使用零压缩法缩短输入。如果几个连续段位的值都是“0”,那么这些“0”就可以简单地以“::”来表示,上面的输入就可以压缩表示如下:


DA70::ABCD:0000:00F7:0003

需要注意的是,只能简化连续为“0”的组,每个组中间和后面的“0”都要保留,比如“DA70”最后的这个“0”不能简化,并且这种简化方式只能用一次,上例中“ABCD”后面的“0000”就不能再进行简化了。这个限制是为了能准确还原被压缩的“0”,不然就无法确定每个“::”究竟代表多少个“0”。不过,各组前导的“0”是可以省略的,如“DA70::ABCD:0000:00F7:0003”与“DA70::ABCD:0000:F7:3”是相同的。

以下几个IPv6地址都是等价的:


DA70:0000:0000:0000:ABCD:0000:00F7:0003
DA70:0000::ABCD:0000:00F7:0003
DA70::ABCD:0000:00F7:0003
DA70:0000:0000:0000:ABCD::00F7:0003
DA70::ABCD:0:F7:3

一个IPv6地址可以将一个IPv4地址内嵌进去,这样就把IPv6的地址写成了IPv6地址和IPv4地址混合的形式。IPv6内嵌IPv4的方式有两种:

·IPv4映像地址。

·IPv4兼容地址。

IPv4映像地址格式如下:


::ffff:192.168.1.100

这个地址仍然是一个IPv6地址,是“::ffff:c0a8:164”的另一种写法。

IPv4兼容地址的写法如下:


::192.168.1.100

这个地址仍然是一个IPv6地址,它是“::c0a8:164”的另一种写法。

inet与cidr的区别

对于inet来说,如果子网掩码是32并且地址是IPv4,那么它不表示任何子网,所表示的只是一台主机的地址,示例如下:


osdba=# select '192.168.1.100/32'::inet;
      inet      
---------------
  192.168.1.100
(1 row)

同样,IPv6地址长度是128位,因此在inet中128位的掩码也表明是一个主机地址,而不是一个子网地址:


osdba=# select '::10.2.3.4/128'::inet;
    inet    
------------
  ::10.2.3.4
(1 row)

而cidr总是显示出掩码,示例如下:


osdba=# select '198.168.1.100'::cidr;
        cidr       
------------------
  198.168.1.100/32
(1 row)

osdba=# select '198.168.1.100/32'::cidr;
        cidr       
------------------
  198.168.1.100/32
(1 row)

cidr总是对地址与掩码之间的关系进行检查,如果不正确会报错,示例如下:


osdba=# select '192.168.1.100/16'::inet;
        inet       
------------------
  192.168.1.100/16
(1 row)

osdba=# select '192.168.1.100/16'::cidr;
ERROR:  invalid cidr value: "192.168.1.100/16"
LINE 1: select '192.168.1.100/16'::cidr;
               ^
DETAIL:  Value has bits set to right of mask.

5.10.3 macaddr类型

macaddr类型用于存储以太网的MAC地址,可以接受多种自定义格式,示例如下:


'00:e0:4c:75:7d:5a' 
'00-e0-4c-75-7d-5a' 
'00e04c-757d5a' 
'00e04c:757d5a' 
'00e0.4c75.7d5a' 
'00e04c757d5a'

上面声明的是同一个MAC地址。对于数据位中的“a”到“f”,大小写都可以。输出总是上面的第一种形式,示例如下:


osdba=# select '00e04c757d5a'::macaddr;
      macaddr      
-------------------
  00:e0:4c:75:7d:5a
(1 row)

osdba=# select '00e04c:757d5a'::macaddr;
      macaddr      
-------------------
  00:e0:4c:75:7d:5a
(1 row)

osdba=# select '00-e0-4c-75-7d-5a'::macaddr;
      macaddr      
-------------------
  00:e0:4c:75:7d:5a
(1 row)

5.10.4 网络地址类型的操作符

可用于cidr类型和inet类型的操作符及其示例见表5-26。

表5-26 cidr和inet类型的操作符

macaddr类型支持一些简单的比较运算符和位运算符,具体见表5-27。

表5-27 macaddr类型支持的操作符

5.10.5 网络地址类型的函数

可以用于cidr类型和inet类型的函数及其示例见表5-28。

表5-28 网络地址类型函数

可用于macaddr类型的函数只有一个trunc(macaddr),此函数把MAC地址的后3个字节置为0,示例如下: SFirkxyjfTdU8F0Jz8heHA3bBMgM7DBIZg/VgDfeagEkXviN3ZNr90HZak0deRxY


osdba=# select  trunc(macaddr '00e04c757d5a');
        trunc       
-------------------
  00:e0:4c:00:00:00
(1 row)

点击中间区域
呼出菜单
上一章
目录
下一章
×