我正在使用ipv4和ipv6存储在postgres db中。
因为ipv4需要32位(4字节)而ipv6需要128(16byte)位。那么为什么在postgres中CIDR和INET数据类型的存储分别为IPV4和IPV6(8.1)的12字节和24字节。
9.1,对于IPV4和IPV6分别有7字节和19字节。
我不明白为什么它需要超过16字节的额外字节用于存储IPV6和4字节用于IPV4?
http://www.postgresql.org/docs/8.1/static/datatype-net-types.html
http://www.postgresql.org/docs/9.1/interactive/datatype-net-types.html
答案 0 :(得分:10)
IP数据类型的sourcecode显示:
typedef struct
{
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
unsigned char bits; /* number of bits in netmask */
unsigned char ipaddr[16]; /* up to 128 bits of address */
} inet_struct;
这意味着,除ipaddr
中的“原始”数据外(IP4为4个字节,IP6为16个字节),网络掩码有一个字节,地址族有一个字节(基本上是一个开关)对于IP4 / IP6)。
此外,同一文件中提到了varlena
开销:
/*
* Both INET and CIDR addresses are represented within Postgres as varlena
* objects, ie, there is a varlena header in front of the struct type
* depicted above. This struct depicts what we actually have in memory
* in "uncompressed" cases. Note that since the maximum data size is only
* 18 bytes, INET/CIDR will invariably be stored into tuples using the
* 1-byte-header varlena format. However, we have to be prepared to cope
* with the 4-byte-header format too, because various code may helpfully
* try to "decompress" 1-byte-header datums.
*/
typedef struct
{
char vl_len_[4]; /* Do not touch this field directly! */
inet_struct inet_data;
} inet;
所以IP4的等式是:
1 byte varlena
1 byte address family
1 byte netmask
4 raw bytes
===========
7 byte total
对于IP6,相同的公式为您提供19个字节。
编辑较早版本的PostgreSQL只有4字节的varlena表示。因此,您可以为每种类型添加3个字节(IP4:10,IP6:22)。最重要的是,填充到下一个4字节边框。这为每种类型提供了2个字节,最多可添加12或24个字节。
This mail阐明了较短版本的发展。