range_hashed
딕셔너리는 정렬된 범위 배열과 해당 값을 포함하는 해시 테이블 형태로 메모리에 저장됩니다.
이 저장 메서드는 hashed와 동일하게 작동하며, 키에 더해 날짜/시간(임의의 숫자 유형) 범위도 사용할 수 있습니다.
예시: 테이블에는 각 광고주의 할인 정보가 다음 포맷으로 저장되어 있습니다:
┌─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 │
└───────────────┴─────────────────────┴───────────────────┴────────┘날짜 범위에 샘플을 사용하려면 구조에 range_min 및 range_max 요소를 정의합니다. 이 요소들에는 name과 type 요소가 포함되어야 합니다(type을 지정하지 않으면 기본 유형인 Date가 사용됩니다). type은 임의의 숫자 유형(Date / DateTime / UInt64 / Int32 / 기타)일 수 있습니다.
예시:
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)<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>
...이러한 딕셔너리를 사용하려면 범위가 선택될 수 있도록 dictGet 함수에 추가 인수를 전달해야 합니다:
dictGet('dict_name', 'attr_name', id, date)쿼리 예시:
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)을 사용할 수 있습니다.
구성 예시:
CREATE DICTIONARY somedict(
Abcdef UInt64,
StartTimeStamp UInt64,
EndTimeStamp UInt64,
XXXType String DEFAULT ''
)
PRIMARY KEY Abcdef
RANGE(MIN StartTimeStamp MAX EndTimeStamp)<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>겹치는 범위와 열린 범위를 포함하는 구성 예시:
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;
┌complex_key_range_hashed
딕셔너리는 범위와 해당 값의 정렬된 배열을 포함하는 해시 테이블 형태로 메모리에 저장됩니다(range_hashed 참조). 이 저장 방식은 복합 키에 사용됩니다.
구성 예시:
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);