メインコンテンツへスキップ

range_hashed

Dictionary は、順序付けられた範囲の Array とそれに対応する値を持つハッシュテーブルの形式で、メモリ内に格納されます。 この格納方式は 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 │
└───────────────┴─────────────────────┴───────────────────┴────────┘
日付範囲にサンプルを使用するには、structurerange_min 要素と range_max 要素を定義します。これらの要素には name 要素と type 要素を含める必要があります (type が指定されていない場合は、デフォルトの型である Date が使用されます) 。type には任意の数値型 (Date / DateTime / UInt64 / Int32 / その他) を指定できます。
range_minrange_max の値は Int64 型に収まる必要があります。
例:
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)

これらの Dictionary を使用するには、範囲の選択対象となる追加の引数を 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_minrange_max が同じ場合) は、その中からランダムに 1 つの範囲を返します。
  • 重複する範囲があり、range_lookup_strategy=max の場合は、一致した範囲のうち range_min が最大のものを返します。該当する範囲が複数ある場合は、range_max が最大の範囲を返します。それでも複数ある場合 (複数の範囲で range_minrange_max が同じ場合) は、その中からランダムに 1 つの範囲を返します。
  • range_maxNULL の場合、その範囲は上限なしになります。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)

重複する範囲と開区間を含む設定例:
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─┐
12015-01-01 │              ᴺᵁᴸᴸ │    0.1
12015-01-15 │              ᴺᵁᴸᴸ │    0.2
22015-01-012015-01-150.3
22015-01-042015-01-100.4
31970-01-012015-01-150.5
31970-01-012015-01-100.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-- 一致する範囲は1つのみ: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
0.2-- 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-- 2つの範囲が一致、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-- 2つの範囲が一致、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-- 一致する範囲は1つのみ: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
0.1-- 2つの範囲が一致、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-- 2つの範囲が一致、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-- 2つの範囲が一致、range_min は等しく、2015-01-10 (0.6) は 2015-01-15 (0.5) より小さい
└─────┘

complex_key_range_hashed

Dictionary は、順序付けされた範囲の Array と、それに対応する値を持つハッシュテーブルの形式でメモリ内に格納されます (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);
最終更新日 2026年6月10日