> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ip_trie 字典布局

> 将字典存储为 trie，以实现快速 IP 地址前缀查找。

`ip_trie` 字典专为按网络前缀查找 IP 地址而设计。
它以 CIDR 表示法存储 IP 范围，并可快速确定给定 IP 属于哪个前缀 (例如子网或 ASN 范围) ，因此非常适合用于基于 IP 的搜索场景，例如地理定位或网络分类。

<Frame>
  <iframe src="https://www.youtube.com/embed/4dxMAqltygk?si=rrQrneBReK6lLfza" title="使用 ip_trie 字典进行基于 IP 的搜索" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

**示例**

假设我们在 ClickHouse 中有一张表，其中包含 IP 前缀及其映射关系：

```sql theme={null}
CREATE TABLE my_ip_addresses (
    prefix String,
    asn UInt32,
    cca2 String
)
ENGINE = MergeTree
PRIMARY KEY prefix;
```

```sql theme={null}
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` 布局需要复合键：

<Tabs>
  <Tab title="DDL">
    ```sql theme={null}
    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);
    ```
  </Tab>

  <Tab title="配置文件">
    ```xml theme={null}
    <structure>
        <key>
            <attribute>
                <name>prefix</name>
                <type>String</type>
            </attribute>
        </key>
        <attribute>
                <name>asn</name>
                <type>UInt32</type>
                <null_value />
        </attribute>
        <attribute>
                <name>cca2</name>
                <type>String</type>
                <null_value>??</null_value>
        </attribute>
        ...
    </structure>
    <layout>
        <ip_trie>
            <!-- 键属性 `prefix` 可通过 dictGetString 获取。 -->
            <!-- 此选项会增加内存占用。 -->
            <access_to_key_from_attributes>true</access_to_key_from_attributes>
        </ip_trie>
    </layout>
    ```
  </Tab>
</Tabs>

<br />

该键必须且只能包含一个 `String` 类型的属性，并且该属性必须包含合法的 IP 前缀。暂不支持其他类型。

语法如下：

```sql theme={null}
dictGetT('dict_name', 'attr_name', ip)
```

该函数接受 `UInt32` (用于 IPv4) 或 `FixedString(16)` (用于 IPv6) 。例如：

```sql theme={null}
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。
