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

# range_hashed 딕셔너리 레이아웃 유형

> 정렬된 날짜/시간 범위를 사용하는 해시 테이블로 딕셔너리를 메모리에 저장합니다.

<div id="range_hashed">
  ## range\_hashed
</div>

딕셔너리는 정렬된 범위 배열과 해당 값을 포함하는 해시 테이블 형태로 메모리에 저장됩니다.

이 저장 메서드는 hashed와 동일하게 작동하며, 키에 더해 날짜/시간(임의의 숫자 유형) 범위도 사용할 수 있습니다.

예시: 테이블에는 각 광고주의 할인 정보가 다음 포맷으로 저장되어 있습니다:

```text theme={null}
┌─advertiser_id─┬─discount_start_date─┬─discount_end_date─┬─amount─┐
│           123 │          2015-01-16 │        2015-01-31 │   0.25 │
│           123 │          2015-01-01 │        2015-01-15 │   0.15 │
│           456 │          2015-01-01 │        2015-01-15 │   0.05 │
└───────────────┴─────────────────────┴───────────────────┴────────┘
```

날짜 범위에 샘플을 사용하려면 [구조](/ko/reference/statements/create/dictionary/attributes#composite-key)에 `range_min` 및 `range_max` 요소를 정의합니다. 이 요소들에는 `name`과 `type` 요소가 포함되어야 합니다(`type`을 지정하지 않으면 기본 유형인 Date가 사용됩니다). `type`은 임의의 숫자 유형(Date / DateTime / UInt64 / Int32 / 기타)일 수 있습니다.

<Note>
  `range_min` 및 `range_max` 값은 `Int64` 유형에 맞아야 합니다.
</Note>

예시:

<Tabs>
  <Tab title="DDL">
    ```sql theme={null}
    CREATE DICTIONARY discounts_dict (
        advertiser_id UInt64,
        discount_start_date Date,
        discount_end_date Date,
        amount Float64
    )
    PRIMARY KEY id
    SOURCE(CLICKHOUSE(TABLE 'discounts'))
    LIFETIME(MIN 1 MAX 1000)
    LAYOUT(RANGE_HASHED(range_lookup_strategy 'max'))
    RANGE(MIN discount_start_date MAX discount_end_date)
    ```
  </Tab>

  <Tab title="설정 파일">
    ```xml theme={null}
    <layout>
        <range_hashed>
            <!-- 겹치는 범위에 대한 전략(min/max)입니다. 기본값: min (min(range_min -> range_max) 값을 갖는 일치 범위를 반환) -->
            <range_lookup_strategy>min</range_lookup_strategy>
        </range_hashed>
    </layout>
    <structure>
        <id>
            <name>advertiser_id</name>
        </id>
        <range_min>
            <name>discount_start_date</name>
            <type>Date</type>
        </range_min>
        <range_max>
            <name>discount_end_date</name>
            <type>Date</type>
        </range_max>
        ...
    ```
  </Tab>
</Tabs>

<br />

이러한 딕셔너리를 사용하려면 범위가 선택될 수 있도록 `dictGet` 함수에 추가 인수를 전달해야 합니다:

```sql theme={null}
dictGet('dict_name', 'attr_name', id, date)
```

쿼리 예시:

```sql theme={null}
SELECT dictGet('discounts_dict', 'amount', 1, '2022-10-20'::Date);
```

이 함수는 지정된 `id`에 대해, 전달된 날짜를 포함하는 날짜 범위의 값을 반환합니다.

알고리즘의 세부 사항은 다음과 같습니다.

* `id`를 찾을 수 없거나 해당 `id`에 대한 범위를 찾을 수 없으면, 속성 타입의 기본값을 반환합니다.
* 겹치는 범위가 있고 `range_lookup_strategy=min`이면, `range_min`이 가장 작은 일치 범위를 반환합니다. 여러 범위를 찾으면 `range_max`가 가장 작은 범위를 반환하고, 여전히 여러 범위가 있으면(`range_min`과 `range_max`가 같은 범위가 여러 개인 경우) 그중 임의의 범위를 반환합니다.
* 겹치는 범위가 있고 `range_lookup_strategy=max`이면, `range_min`이 가장 큰 일치 범위를 반환합니다. 여러 범위를 찾으면 `range_max`가 가장 큰 범위를 반환하고, 여전히 여러 범위가 있으면(`range_min`과 `range_max`가 같은 범위가 여러 개인 경우) 그중 임의의 범위를 반환합니다.
* `range_max`가 `NULL`이면 해당 범위는 열린 범위입니다. `NULL`은 가능한 최댓값으로 처리됩니다. `range_min`에는 열린 값으로 `1970-01-01` 또는 `0` (-MAX\_INT)을 사용할 수 있습니다.

구성 예시:

<Tabs>
  <Tab title="DDL">
    ```sql theme={null}
    CREATE DICTIONARY somedict(
        Abcdef UInt64,
        StartTimeStamp UInt64,
        EndTimeStamp UInt64,
        XXXType String DEFAULT ''
    )
    PRIMARY KEY Abcdef
    RANGE(MIN StartTimeStamp MAX EndTimeStamp)
    ```
  </Tab>

  <Tab title="설정 파일">
    ```xml theme={null}
    <clickhouse>
        <dictionary>
            ...

            <layout>
                <range_hashed />
            </layout>

            <structure>
                <id>
                    <name>Abcdef</name>
                </id>
                <range_min>
                    <name>StartTimeStamp</name>
                    <type>UInt64</type>
                </range_min>
                <range_max>
                    <name>EndTimeStamp</name>
                    <type>UInt64</type>
                </range_max>
                <attribute>
                    <name>XXXType</name>
                    <type>String</type>
                    <null_value />
                </attribute>
            </structure>

        </dictionary>
    </clickhouse>
    ```
  </Tab>
</Tabs>

<br />

겹치는 범위와 열린 범위를 포함하는 구성 예시:

```sql theme={null}
CREATE TABLE discounts
(
    advertiser_id UInt64,
    discount_start_date Date,
    discount_end_date Nullable(Date),
    amount Float64
)
ENGINE = Memory;

INSERT INTO discounts VALUES (1, '2015-01-01', Null, 0.1);
INSERT INTO discounts VALUES (1, '2015-01-15', Null, 0.2);
INSERT INTO discounts VALUES (2, '2015-01-01', '2015-01-15', 0.3);
INSERT INTO discounts VALUES (2, '2015-01-04', '2015-01-10', 0.4);
INSERT INTO discounts VALUES (3, '1970-01-01', '2015-01-15', 0.5);
INSERT INTO discounts VALUES (3, '1970-01-01', '2015-01-10', 0.6);

SELECT * FROM discounts ORDER BY advertiser_id, discount_start_date;
┌─advertiser_id─┬─discount_start_date─┬─discount_end_date─┬─amount─┐
│             1 │          2015-01-01 │              ᴺᵁᴸᴸ │    0.1 │
│             1 │          2015-01-15 │              ᴺᵁᴸᴸ │    0.2 │
│             2 │          2015-01-01 │        2015-01-15 │    0.3 │
│             2 │          2015-01-04 │        2015-01-10 │    0.4 │
│             3 │          1970-01-01 │        2015-01-15 │    0.5 │
│             3 │          1970-01-01 │        2015-01-10 │    0.6 │
└───────────────┴─────────────────────┴───────────────────┴────────┘

-- RANGE_LOOKUP_STRATEGY 'max'

CREATE DICTIONARY discounts_dict
(
    advertiser_id UInt64,
    discount_start_date Date,
    discount_end_date Nullable(Date),
    amount Float64
)
PRIMARY KEY advertiser_id
SOURCE(CLICKHOUSE(TABLE discounts))
LIFETIME(MIN 600 MAX 900)
LAYOUT(RANGE_HASHED(RANGE_LOOKUP_STRATEGY 'max'))
RANGE(MIN discount_start_date MAX discount_end_date);

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-14')) res;
┌─res─┐
│ 0.1 │ -- 일치하는 범위가 하나뿐입니다: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
│ 0.2 │ -- 두 범위가 일치하며, range_min 2015-01-15 (0.2)이 2015-01-01 (0.1)보다 큽니다
└─────┘

select dictGet('discounts_dict', 'amount', 2, toDate('2015-01-06')) res;
┌─res─┐
│ 0.4 │ -- 두 범위가 일치하며, range_min 2015-01-04 (0.4)이 2015-01-01 (0.3)보다 큽니다
└─────┘

select dictGet('discounts_dict', 'amount', 3, toDate('2015-01-01')) res;
┌─res─┐
│ 0.5 │ -- 두 범위가 일치하며, range_min이 동일하고 2015-01-15 (0.5)이 2015-01-10 (0.6)보다 큽니다
└─────┘

DROP DICTIONARY discounts_dict;

-- RANGE_LOOKUP_STRATEGY 'min'

CREATE DICTIONARY discounts_dict
(
    advertiser_id UInt64,
    discount_start_date Date,
    discount_end_date Nullable(Date),
    amount Float64
)
PRIMARY KEY advertiser_id
SOURCE(CLICKHOUSE(TABLE discounts))
LIFETIME(MIN 600 MAX 900)
LAYOUT(RANGE_HASHED(RANGE_LOOKUP_STRATEGY 'min'))
RANGE(MIN discount_start_date MAX discount_end_date);

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-14')) res;
┌─res─┐
│ 0.1 │ -- 일치하는 범위가 하나뿐입니다: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
│ 0.1 │ -- 두 범위가 일치하며, range_min 2015-01-01 (0.1)이 2015-01-15 (0.2)보다 작습니다
└─────┘

select dictGet('discounts_dict', 'amount', 2, toDate('2015-01-06')) res;
┌─res─┐
│ 0.3 │ -- 두 범위가 일치하며, range_min 2015-01-01 (0.3)이 2015-01-04 (0.4)보다 작습니다
└─────┘

select dictGet('discounts_dict', 'amount', 3, toDate('2015-01-01')) res;
┌─res─┐
│ 0.6 │ -- 두 범위가 일치하며, range_min이 동일하고 2015-01-10 (0.6)이 2015-01-15 (0.5)보다 작습니다
└─────┘
```

<div id="complex_key_range_hashed">
  ## complex\_key\_range\_hashed
</div>

딕셔너리는 범위와 해당 값의 정렬된 배열을 포함하는 해시 테이블 형태로 메모리에 저장됩니다([range\_hashed](#range_hashed) 참조). 이 저장 방식은 복합 [키](/ko/reference/statements/create/dictionary/attributes#composite-key)에 사용됩니다.

구성 예시:

```sql theme={null}
CREATE DICTIONARY range_dictionary
(
  CountryID UInt64,
  CountryKey String,
  StartDate Date,
  EndDate Date,
  Tax Float64 DEFAULT 0.2
)
PRIMARY KEY CountryID, CountryKey
SOURCE(CLICKHOUSE(TABLE 'date_table'))
LIFETIME(MIN 1 MAX 1000)
LAYOUT(COMPLEX_KEY_RANGE_HASHED())
RANGE(MIN StartDate MAX EndDate);
```
