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

> يشير TTL (مدة البقاء) إلى إمكانية نقل الصفوف أو الأعمدة أو حذفها أو تجميعها تلقائيًا بعد انقضاء فترة زمنية محددة.

# إدارة البيانات باستخدام TTL (مدة البقاء)

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            غير مدعوم في ClickHouse Cloud
        </div>;
};

<div id="overview-of-ttl">
  ## نظرة عامة على TTL
</div>

يشير TTL ‏(مدة البقاء) إلى إمكانية نقل الصفوف أو الأعمدة أو حذفها أو تلخيصها بعد انقضاء مدة زمنية معيّنة. ورغم أن مصطلح "مدة البقاء" يوحي بأنه يقتصر على حذف البيانات القديمة، فإن لـ TTL عدة حالات استخدام:

* إزالة البيانات القديمة: لا مفاجأة هنا، إذ يمكنك حذف الصفوف أو الأعمدة بعد مدة زمنية محددة
* نقل البيانات بين الأقراص: بعد مرور فترة معيّنة، يمكنك نقل البيانات بين وحدات التخزين، وهو ما يفيد في نشر معمارية hot/warm/cold
* تلخيص البيانات: يمكنك تلخيص بياناتك الأقدم في تجميعات وعمليات احتساب مفيدة متنوعة قبل حذفها

<Note>
  يمكن تطبيق TTL على جداول كاملة أو على أعمدة محددة.
</Note>

<div id="ttl-syntax">
  ## بنية TTL
</div>

يمكن أن تَرِد عبارة `TTL` بعد تعريف عمود و/أو في نهاية تعريف الجدول. استخدم عبارة `INTERVAL` لتحديد فترة زمنية (ويجب أن تكون من نوع البيانات `Date` أو `DateTime`). على سبيل المثال، يحتوي الجدول التالي على عمودين
مع عبارتي `TTL`:

```sql theme={null}
CREATE TABLE example1 (
   timestamp DateTime,
   x UInt32 TTL timestamp + INTERVAL 1 MONTH,
   y String TTL timestamp + INTERVAL 1 DAY,
   z String
)
ENGINE = MergeTree
ORDER BY tuple()
```

* يحتوي العمود x على مدة بقاء قدرها شهر واحد بدءًا من عمود الطابع الزمني
* يحتوي العمود y على مدة بقاء قدرها يوم واحد بدءًا من عمود الطابع الزمني
* عند انقضاء الفاصل الزمني، تنتهي صلاحية العمود. يستبدل ClickHouse قيمة العمود بالقيمة الافتراضية لنوع بياناته. وإذا انتهت صلاحية جميع قيم العمود في جزء البيانات، يحذف ClickHouse هذا العمود من جزء البيانات في نظام الملفات.

<Note>
  يمكن تعديل قواعد TTL أو حذفها. راجع صفحة [إجراءات TTL للجدول](/ar/reference/statements/alter/ttl) لمزيد من التفاصيل.
</Note>

<Tip>
  **أفضل الممارسات**

  عند استخدام TTL على مستوى الجدول لإزالة الصفوف القديمة، نوصي بأن **تُقسِّم جدولك حسب التاريخ أو الشهر** للحقل الزمني نفسه المستخدم في تعبير TTL.

  يمكن لـ ClickHouse حذف أقسام كاملة بكفاءة أعلى بكثير من حذف صفوف فردية.
  وعندما يتوافق مفتاح التقسيم مع تعبير TTL، يمكن لـ ClickHouse حذف أقسام كاملة دفعة واحدة عند انتهاء صلاحيتها، بدلًا من إعادة كتابة أجزاء البيانات لإزالة الصفوف منتهية الصلاحية.

  اختر درجة التقسيم بناءً على فترة TTL:

  * بالنسبة إلى TTL بالأيام/الأسابيع: قسّم حسب اليوم باستخدام `toYYYYMMDD(date_field)`
  * بالنسبة إلى TTL بالأشهر/السنوات: قسّم حسب الشهر باستخدام `toYYYYMM(date_field)` أو `toStartOfMonth(date_field)`
</Tip>

<div id="triggering-ttl-events">
  ## تشغيل أحداث TTL
</div>

إن حذف الصفوف منتهية الصلاحية أو تجميعها لا يحدث فورًا، بل لا يتم إلا أثناء عمليات دمج الجدول. وإذا كان لديك جدول لا تُجرى له عمليات دمج بشكل نشط (لأي سبب كان)، فهناك إعدادان يُشغّلان أحداث TTL:

* `merge_with_ttl_timeout`: الحد الأدنى للتأخير بالثواني قبل تكرار عملية دمج مع TTL للحذف. القيمة الافتراضية هي 14400 ثانية (4 ساعات).
* `merge_with_recompression_ttl_timeout`: الحد الأدنى للتأخير بالثواني قبل تكرار عملية دمج مع TTL لإعادة الضغط (القواعد التي تُجمّع البيانات قبل حذفها). القيمة الافتراضية: 14400 ثانية (4 ساعات).

لذلك، وبشكل افتراضي، ستُطبَّق قواعد TTL على جدولك مرة واحدة على الأقل كل 4 ساعات. ما عليك سوى تعديل الإعدادات أعلاه إذا كنت بحاجة إلى تطبيق قواعد TTL بوتيرة أعلى.

<Note>
  ليس هذا حلًا مثاليًا (ولا نوصي باستخدامه كثيرًا)، ولكن يمكنك أيضًا فرض عملية دمج باستخدام `OPTIMIZE`:

  ```sql theme={null}
  OPTIMIZE TABLE example1 FINAL
  ```

  يبدأ `OPTIMIZE` عملية دمج غير مجدولة لأجزاء جدولك، بينما يفرض `FINAL` إعادة التحسين إذا كان جدولك يتكوّن بالفعل من جزء واحد.
</Note>

<div id="removing-rows">
  ## إزالة الصفوف
</div>

لإزالة صفوف كاملة من جدول بعد فترة زمنية معينة، حدِّد قاعدة TTL على مستوى الجدول:

```sql theme={null}
CREATE TABLE customers (
timestamp DateTime,
name String,
balance Int32,
address String
)
ENGINE = MergeTree
ORDER BY timestamp
TTL timestamp + INTERVAL 12 HOUR
```

بالإضافة إلى ذلك، يمكن تعريف قاعدة TTL استنادًا إلى قيمة السجل.
ويمكن تنفيذ ذلك بسهولة عبر تحديد شرط WHERE.
ويُسمح بوجود شروط متعددة:

```sql theme={null}
CREATE TABLE events
(
    `event` String,
    `time` DateTime,
    `value` UInt64
)
ENGINE = MergeTree
ORDER BY (event, time)
TTL time + INTERVAL 1 MONTH DELETE WHERE event != 'error',
    time + INTERVAL 6 MONTH DELETE WHERE event = 'error'
```

<div id="removing-columns">
  ## إزالة الأعمدة
</div>

بدلًا من حذف الصف بأكمله، لنفترض أنك تريد فقط انتهاء صلاحية عمودي الرصيد والعنوان. لنعدّل جدول `customers` ونضيف قيمة TTL لكلا العمودين لمدة ساعتين:

```sql theme={null}
ALTER TABLE customers
MODIFY COLUMN balance Int32 TTL timestamp + INTERVAL 2 HOUR,
MODIFY COLUMN address String TTL timestamp + INTERVAL 2 HOUR
```

<div id="implementing-a-rollup">
  ## تنفيذ عملية تلخيص
</div>

لنفترض أننا نريد حذف الصفوف بعد مرور فترة زمنية معينة، مع الاحتفاظ ببعض البيانات لأغراض إعداد التقارير. نحن لا نحتاج إلى كل التفاصيل، بل إلى بعض النتائج المجمّعة فقط من البيانات التاريخية. يمكن تنفيذ ذلك بإضافة عبارة `GROUP BY` إلى تعبير `TTL`، إلى جانب بعض الأعمدة في جدولك لتخزين النتائج المجمّعة.

لنفترض أننا نريد، في جدول `hits` التالي، حذف الصفوف القديمة مع الاحتفاظ بمجموع القيم والقيمة العظمى لأعمدة `hits` قبل إزالة الصفوف. سنحتاج إلى حقل لتخزين هذه القيم، كما سنحتاج إلى إضافة عبارة `GROUP BY` إلى عبارة `TTL` لتنفيذ تلخيص للمجموع والقيمة العظمى:

```sql theme={null}
CREATE TABLE hits (
   timestamp DateTime,
   id String,
   hits Int32,
   max_hits Int32 DEFAULT hits,
   sum_hits Int64 DEFAULT hits
)
ENGINE = MergeTree
PRIMARY KEY (id, toStartOfDay(timestamp), timestamp)
TTL timestamp + INTERVAL 1 DAY
    GROUP BY id, toStartOfDay(timestamp)
    SET
        max_hits = max(max_hits),
        sum_hits = sum(sum_hits);
```

بعض الملاحظات حول جدول `hits`:

* يجب أن تكون الأعمدة في عبارة `GROUP BY` ضمن عبارة `TTL` بادئة لـ `PRIMARY KEY`، ونريد تجميع نتائجنا حسب بداية اليوم. لذلك أُضيفت `toStartOfDay(timestamp)` إلى المفتاح الأساسي
* أضفنا حقلين لتخزين النتائج المجمّعة: `max_hits` و `sum_hits`
* إن تعيين القيمة الافتراضية لـ `max_hits` و `sum_hits` إلى `hits` ضروري لعمل هذا المنطق، استنادًا إلى كيفية تعريف عبارة `SET`

<div id="implementing-a-hotwarmcold-architecture">
  ## تنفيذ معمارية hot/warm/cold
</div>

<Note>
  إذا كنت تستخدم ClickHouse Cloud، فلن تنطبق الخطوات الواردة في هذا الدرس. ولا داعي للقلق بشأن نقل البيانات القديمة داخل ClickHouse Cloud.
</Note>

من الممارسات الشائعة عند العمل مع كميات كبيرة من البيانات نقلها كلما تقادمت. في ما يلي خطوات تنفيذ معمارية hot/warm/cold في ClickHouse باستخدام العبارتين `TO DISK` و`TO VOLUME` في الأمر `TTL`. (وبالمناسبة، لا يقتصر الأمر على hot وcold فقط — إذ يمكنك استخدام `TTL` لنقل البيانات وفقًا لأي حالة استخدام لديك.)

1. يشير الخياران `TO DISK` و`TO VOLUME` إلى أسماء الأقراص أو وحدات التخزين المعرّفة في ملفات تكوين ClickHouse. أنشئ ملفًا جديدًا باسم `my_system.xml` (أو بأي اسم ملف آخر) لتعريف الأقراص، ثم عرّف وحدات تخزين تستخدم هذه الأقراص. ضع ملف XML في `/etc/clickhouse-server/config.d/` لتطبيق الإعدادات على نظامك:

```xml theme={null}
<clickhouse>
    <storage_configuration>
        <disks>
            <default>
            </default>
           <hot_disk>
              <path>./hot/</path>
           </hot_disk>
           <warm_disk>
              <path>./warm/</path>
           </warm_disk>
           <cold_disk>
              <path>./cold/</path>
           </cold_disk>
        </disks>
        <policies>
            <default>
                <volumes>
                    <default>
                        <disk>default</disk>
                    </default>
                    <hot_volume>
                        <disk>hot_disk</disk>
                    </hot_volume>
                    <warm_volume>
                        <disk>warm_disk</disk>
                    </warm_volume>
                    <cold_volume>
                        <disk>cold_disk</disk>
                    </cold_volume>
                </volumes>
            </default>
        </policies>
    </storage_configuration>
</clickhouse>
```

2. يشير التكوين أعلاه إلى ثلاثة أقراص تشير إلى مجلدات يمكن لـ ClickHouse القراءة منها والكتابة إليها. ويمكن أن تحتوي وحدات التخزين على قرص واحد أو أكثر - وقد عرّفنا وحدة تخزين لكل قرص من الأقراص الثلاثة. لنستعرض الأقراص:

```sql theme={null}
SELECT name, path, free_space, total_space
FROM system.disks
```

```response theme={null}
┌─name────────┬─path───────────┬───free_space─┬──total_space─┐
│ cold_disk   │ ./data/cold/   │ 179143311360 │ 494384795648 │
│ default     │ ./             │ 179143311360 │ 494384795648 │
│ hot_disk    │ ./data/hot/    │ 179143311360 │ 494384795648 │
│ warm_disk   │ ./data/warm/   │ 179143311360 │ 494384795648 │
└─────────────┴────────────────┴──────────────┴──────────────┘
```

3. والآن... لنتأكد من وحدات التخزين:

```sql theme={null}
SELECT
    volume_name,
    disks
FROM system.storage_policies
```

```response theme={null}
┌─volume_name─┬─disks─────────┐
│ default     │ ['default']   │
│ hot_volume  │ ['hot_disk']  │
│ warm_volume │ ['warm_disk'] │
│ cold_volume │ ['cold_disk'] │
└─────────────┴───────────────┘
```

4. سنضيف الآن قاعدة `TTL` تنقل البيانات بين وحدات التخزين الساخنة والدافئة والباردة:

```sql theme={null}
ALTER TABLE my_table
   MODIFY TTL
      trade_date TO VOLUME 'hot_volume',
      trade_date + INTERVAL 2 YEAR TO VOLUME 'warm_volume',
      trade_date + INTERVAL 4 YEAR TO VOLUME 'cold_volume';
```

5. يجب أن تدخل قاعدة `TTL` الجديدة حيّز التنفيذ، ولكن يمكنك فرض ذلك للتأكد:

```sql theme={null}
ALTER TABLE my_table
    MATERIALIZE TTL
```

6. تحقّق من انتقال بياناتك إلى الأقراص المتوقعة باستخدام الجدول `system.parts`:

```sql theme={null}
Using the system.parts table, view which disks the parts are on for the crypto_prices table:

SELECT
    name,
    disk_name
FROM system.parts
WHERE (table = 'my_table') AND (active = 1)
```

سيكون الإخراج كما يلي:

```response theme={null}
┌─name────────┬─disk_name─┐
│ all_1_3_1_5 │ warm_disk │
│ all_2_2_0   │ hot_disk  │
└─────────────┴───────────┘
```
