跳转到主要内容
ip_trie 字典专为按网络前缀查找 IP 地址而设计。 它以 CIDR 表示法存储 IP 范围,并可快速确定给定 IP 属于哪个前缀 (例如子网或 ASN 范围) ,因此非常适合用于基于 IP 的搜索场景,例如地理定位或网络分类。
示例 假设我们在 ClickHouse 中有一张表,其中包含 IP 前缀及其映射关系:
CREATE TABLE my_ip_addresses (
    prefix String,
    asn UInt32,
    cca2 String
)
ENGINE = MergeTree
PRIMARY KEY prefix;
INSERT INTO my_ip_addresses VALUES
    ('202.79.32.0/20', 17501, 'NP'),
    ('2620:0:870::/48', 3856, 'US'),
    ('2a02:6b8:1::/48', 13238, 'RU'),
    ('2001:db8::/32', 65536, 'ZZ')
;
让我们为这个表定义一个 ip_trie 字典。ip_trie 布局需要复合键:
CREATE DICTIONARY my_ip_trie_dictionary (
    prefix String,
    asn UInt32,
    cca2 String DEFAULT '??'
)
PRIMARY KEY prefix
SOURCE(CLICKHOUSE(TABLE 'my_ip_addresses'))
LAYOUT(IP_TRIE)
LIFETIME(3600);

该键必须且只能包含一个 String 类型的属性,并且该属性必须包含合法的 IP 前缀。暂不支持其他类型。 语法如下:
dictGetT('dict_name', 'attr_name', ip)
该函数接受 UInt32 (用于 IPv4) 或 FixedString(16) (用于 IPv6) 。例如:
SELECT dictGet('my_ip_trie_dictionary', 'cca2', toIPv4('202.79.32.10')) AS result;

┌─result─┐
│ NP     │
└────────┘

SELECT dictGet('my_ip_trie_dictionary', 'asn', IPv6StringToNum('2001:db8::1')) AS result;

┌─result─┐
65536
└────────┘

SELECT dictGet('my_ip_trie_dictionary', ('asn', 'cca2'), IPv6StringToNum('2001:db8::1')) AS result;

┌─result───────┐
│ (65536,'ZZ') │
└──────────────┘
暂不支持其他类型。该函数会返回与此 IP 地址对应前缀的 attribute。如果存在重叠的前缀,则返回最具体的那个。 数据必须完全装入 RAM。
最后修改于 2026年6月10日