本文介紹了ip4r外掛程式的背景資訊、資料類型以及使用方法等內容。
適用範圍
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 17(核心小版本2.0.17.6.4.0及以上)
PostgreSQL 16(核心小版本2.0.16.9.9.0及以上)
PostgreSQL 15(核心小版本2.0.15.14.6.0及以上)
PostgreSQL 14(核心小版本2.0.14.9.13.0及以上)
PostgreSQL 11(核心小版本2.0.11.9.36.0及以上)
背景資訊
ip4r是PolarDB PostgreSQL版支援的一款第三方外掛程式,支援儲存IPv4或IPv6資料類型。與PostgreSQL提供的相關內建資料類型inet/cidr不同,ip4r支援對包含操作符>>=進行索引掃描。除此之外,ip4r相對於PostgreSQL內建的網路資料類型還有以下特點:
語義清晰:將網路塊與網路塊內的特定IP地址兩種語義進行了明確區分。
開銷更低:PostgreSQL為支援儲存IPv6資料而使用了變長資料類型,對明確需要儲存IPv4資料的情境來說是不小的開銷。
ip4r對單一地址資料將使用定長資料類型。
資料類型
ip4r提供了豐富的資料類型來支援儲存、表示IPv4或IPv6資料:
資料類型 | 說明 |
ip4 | 單一IPv4地址。 |
ip4r | 任意IPv4位址範圍。 |
ip6 | 單一IPv6地址。 |
ip6r | 任意IPv6位址範圍。 |
ipaddress | 單一IPv4或IPv6地址。 |
iprange | 任意IPv4或IPv6位址範圍。 |
單一地址資料類型及其類型轉換
以下三種資料類型用於儲存單一IP地址資料:
ip4:輸入形式必須滿足nnn.nnn.nnn.nnn,其實際儲存的資料為32位無符號整型資料。ip6:輸入形式必須是IPv6地址的標準十六進位表示形式,其實際儲存的資料為兩個64位元據。ipaddress:輸入形式必須滿足ip4或ip6其中之一。
針對以上三種資料類型,ip4r提供了相應的類型轉換,具體規則如下:
下表中的ipX表示上述三種類型其中之一。
原類型 | 目標類型 | 格式 |
ipX | text | text(ipX) or ipX::text (explicit) |
text | ipX | ipX(text) or text::ipX (explicit) |
ipX | cidr | cidr(ipX) or ipX::cidr (assignment) |
inet | ipX | ipX(inet) or inet::ipX (assignment) |
ipX | numeric | to_numeric(ipX) or ipX::numeric (explicit) |
numeric | ipX | ipX(numeric) or bigint::ipX (explicit) |
ip4 | bigint | to_bigint(ip4) or ip4::bigint (explicit) |
bigint | ip4 | ip4(bigint) or bigint::ip4 (explicit) |
ip4 | float8 | to_double(ip4) or ip4::float8 (explicit) |
float8 | ip4 | ip4(float8) or float8::ip4 (explicit) |
ipX | varbit | to_bit(ipX) or ipX::varbit (explicit) |
bit(32) | ip4 | ip4(bit) or bit::ip4 (explicit) |
bit(128) | ip6 | ip6(bit) or bit::ip6 (explicit) |
varbit | ipX | ipX(varbit) or varbit::ipX (explicit) |
ipX | bytea | to_bytea(ipX) or ipX::bytea (explicit) |
bytea | ipX | ipX(bytea) or bytea::ipX (explicit) |
ipX | ipXr | ipXr(ipX) or ipX::ipXr (implicit) |
ip4 | ipaddress | ipaddress(ip4) or ip4::ipaddress (implicit) |
ip6 | ipaddress | ipaddress(ip6) or ip6::ipaddress (implicit) |
ipaddress | ip4 | ip4(ipaddress) or ipaddress::ip4 (assignment) |
ipaddress | ip6 | ip6(ipaddress) or ipaddress::ip6 (assignment) |
位址範圍資料類型及其類型轉換
以下三種資料類型用於儲存一段IP位址範圍的資料:
ip4r:用於儲存IPv4位址範圍類型的資料,例如192.0.2.100-192.0.2.200、192.0.2.0/24等價於192.0.2.0-192.0.2.255。ip6r:用於儲存IPv6位址範圍類型的資料,例如2001::1234-2001::2000:0000、2001::/112等價於2001::-2001::ffff。iprange:輸入形式必須滿足ip4r或ip6r其中之一。
針對以上三種資料類型,ip4r提供了相應的類型轉換,具體規則如下:
下表中的ipXr表示上述三種類型其中之一。
原類型 | 目標類型 | 格式 |
ipX | ipXr | ipXr(ipX) or ipX::ipXr (implicit) |
ipXr | text | text(ipXr) or ipXr::text (explicit) |
text | ipXr | ipXr(text) or text::ipXr (explicit) |
ipXr | cidr | cidr(ipXr) or ipXr::cidr (explicit) |
cidr | ipXr | ipXr(cidr) or cidr::ipXr (assignment) |
ipXr | varbit | to_bit(ipXr) or ipXr::varbit (explicit) |
varbit | ip4r | ip4r(varbit) or varbit::ip4r (explicit) |
varbit | ip6r | ip6r(varbit) or varbit::ip6r (explicit) |
使用方法
建立外掛程式
CREATE EXTENSION ip4r;建立測試表並匯入資料
CREATE TABLE ipranges (r iprange, r4 ip4r, r6 ip6r);
INSERT INTO ipranges
SELECT r, null, r
FROM (
SELECT ip6r(regexp_replace(ls, E'(....(?!$))', E'\\1:', 'g')::ip6,
regexp_replace(substring(ls FOR n + 1) || substring(us FROM n + 2),
E'(....(?!$))', E'\\1:', 'g')::ip6) AS r
FROM (
SELECT md5(i || ' lower 1') AS ls,
md5(i || ' upper 1') AS us,
(i % 11) + (i/11 % 11) + (i/121 % 11) AS n
FROM generate_series(1,13310) i) s1) s2;建立GiST索引
CREATE INDEX ipranges_r ON ipranges USING gist (r);使用包含操作符
EXPLAIN (COSTS OFF) SELECT * FROM ipranges WHERE r >>= '5555::' ORDER BY r;返回結果如下:
QUERY PLAN
-----------------------------------------------------
Sort
Sort Key: r
-> Bitmap Heap Scan on ipranges
Recheck Cond: (r >>= '5555::'::iprange)
-> Bitmap Index Scan on ipranges_r
Index Cond: (r >>= '5555::'::iprange)
(6 rows)卸載外掛程式
DROP EXTENSION ip4r;