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

# أنواع تخطيط القاموس range_hashed

> تخزين قاموس في الذاكرة باستخدام جدول تجزئة مع نطاقات تاريخ/وقت مرتبة.

## range\_hashed

يُخزَّن القاموس في الذاكرة على شكل جدول تجزئة يتضمن مصفوفة مرتبة من النطاقات والقيم المقابلة لها.

تعمل طريقة التخزين هذه بالطريقة نفسها التي تعمل بها 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 │
└───────────────┴─────────────────────┴───────────────────┴────────┘
```

لاستخدام عيّنة مع نطاقات التاريخ، حدِّد العنصرين `range_min` و`range_max` في [البنية](/ar/reference/statements/create/dictionary/attributes#composite-key). يجب أن يحتوي هذان العنصران على `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>
        ...
    </structure>
    ```
  </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` على أنها أكبر قيمة ممكنة. ويمكن استخدام `1970-01-01` أو `0` (-MAX\_INT) مع `range_min` باعتبارها القيمة المفتوحة.

مثال على التهيئة:

<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 │ -- the only one range is matching: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
│ 0.2 │ -- two ranges are matching, range_min 2015-01-15 (0.2) is bigger than 2015-01-01 (0.1)
└─────┘

select dictGet('discounts_dict', 'amount', 2, toDate('2015-01-06')) res;
┌─res─┐
│ 0.4 │ -- two ranges are matching, range_min 2015-01-04 (0.4) is bigger than 2015-01-01 (0.3)
└─────┘

select dictGet('discounts_dict', 'amount', 3, toDate('2015-01-01')) res;
┌─res─┐
│ 0.5 │ -- two ranges are matching, range_min are equal, 2015-01-15 (0.5) is bigger than 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 │ -- the only one range is matching: 2015-01-01 - Null
└─────┘

select dictGet('discounts_dict', 'amount', 1, toDate('2015-01-16')) res;
┌─res─┐
│ 0.1 │ -- two ranges are matching, range_min 2015-01-01 (0.1) is less than 2015-01-15 (0.2)
└─────┘

select dictGet('discounts_dict', 'amount', 2, toDate('2015-01-06')) res;
┌─res─┐
│ 0.3 │ -- two ranges are matching, range_min 2015-01-01 (0.3) is less than 2015-01-04 (0.4)
└─────┘

select dictGet('discounts_dict', 'amount', 3, toDate('2015-01-01')) res;
┌─res─┐
│ 0.6 │ -- two ranges are matching, range_min are equal, 2015-01-10 (0.6) is less than 2015-01-15 (0.5)
└─────┘
```

## complex\_key\_range\_hashed

يُخزَّن القاموس في الذاكرة على هيئة جدول تجزئة مع مصفوفة مرتبة من النطاقات والقيم المقابلة لها (انظر [range\_hashed](#range_hashed)). يُستخدم هذا النوع من التخزين مع [المفاتيح](/ar/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);
```
