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على أنها أكبر قيمة ممكنة. ويمكن استخدام1970-01-01أو0(-MAX_INT) معrange_minباعتبارها القيمة المفتوحة.
مثال على الإعداد:
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);