由于IPV6需要128位(16字节),为什么在postgres CIDR数据类型中存储为24字节(8.1)和19字节(9.1)?

Ash*_*hti 6 postgresql ipv4 ipv6 cidr inet

我正在使用ipv4和ipv6存储在postgres db中.

因为ipv4需要32位(4字节)而ipv6需要128(16byte)位.那么为什么在postgres中CIDR和INET数据类型的存储分别为IPV4和IPV6(8.1)的12字节和24字节.

对于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

A.H*_*.H. 10

IP数据类型的源代码显示:

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;
Run Code Online (Sandbox Code Playgroud)

这意味着,除了"原始"数据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;
Run Code Online (Sandbox Code Playgroud)

所以IP4的等式是这样的:

1 byte varlena
1 byte address family
1 byte netmask
4 raw bytes
=========== 
7 byte total
Run Code Online (Sandbox Code Playgroud)

对于IP6,相同的公式为您提供19个字节.

编辑旧版本的PostgreSQL只有4字节的varlena表示.因此,您可以为每种类型添加3个字节(IP4:10,IP6:22).最重要的是,填充到下一个4字节边框.这为每种类型提供了2个字节,最多可添加12或24个字节.

这封邮件揭示了较短版本的发展.