7

私はipv4とipv6を使用してpostgresdbに保存しています。

ipv4には32ビット(4バイト)が必要であり、ipv6には128(16バイト)ビットが必要であるため、postgresではCIDRおよびINETデータ型にIPV4およびIPV6(8.1)用にそれぞれ12バイトおよび24バイトのストレージがあります。

9.1では、IPV4とIPV6にそれぞれ7バイトと19バイトがあります。

IPV6を格納するために16バイト以上、IPV4を格納するために4バイト以上の余分なバイトが必要な理由がわかりませんか?

http://www.postgresql.org/docs/8.1/static/datatype-net-types.html

http://www.postgresql.org/docs/9.1/interactive/datatype-net-types.html

4

1 に答える 1

12

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;

これは、(IP4の場合は4バイト、IP6の場合は16バイト)の「生」データに加えてipaddr、ネットマスク用に1バイト、アドレスファミリ用に1バイト(基本的に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バイトになります。

このメールは、短いバージョンの開発に光を当てています。

于 2012-07-18T19:18:57.663 に答える