2012-07-18 28 views
5

我正在使用ipv4和ipv6來存儲postgres數據庫。由於IPV6需要128位(16字節),那麼爲什麼postgres CIDR數據類型的存儲空間爲24字節(8.1)和19字節(9.1)?

由於ipv4需要32位(4字節),而ipv6需要128位(16位)位。因此postgres CIDR和INET數據類型爲什麼分別爲IPV4和IPV6(8.1)存儲12字節和24字節。

與9.1,它分別有7字節和19字節的IPV4和IPV6。

我不明白爲什麼它需要額外的字節多於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

它至少需要+1字節的網絡掩碼位,例如「10.1.0.0/8」對10.1.0.0掩碼有效255.0.0.0 – 2012-07-18 13:52:50

回答

9

sourcecode用於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; 

這意味着,附加的 「原始」 數據在ipaddr(4字節爲IP4,16字節爲IP6)有一個字節的網絡掩碼和一個字節的地址系列(基本上是一個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對短版本的發展有一些啓發。

+0

謝謝... @ A.H..it實際上幫助我.. – 2012-07-19 05:58:46

相關問題