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

# أنشئ أول جدول MergeTree

> تعرّف على آلية عمل محرك الجداول الأساسي في ClickHouse من خلال إنشاء جدول MergeTree، وتحميل بيانات أسعار العقارات في المملكة المتحدة، وملاحظة كيف تؤثر الأجزاء وعمليات الدمج في التخزين وأداء الاستعلام.

<a href="/ar/get-started/quickstarts/home"><Badge size="lg" color="gray" icon="arrow-left">جميع الأدلة السريعة</Badge></a>

<div className="mt-2 flex flex-wrap gap-2">
  <Badge size="lg" color="blue">التحليلات اللحظية</Badge>
  <Badge size="lg" color="blue">مستودعات البيانات</Badge>
  <Badge size="lg" color="blue">الرصد</Badge>
  <Badge size="lg" color="blue">الذكاء الاصطناعي/تعلّم الآلة</Badge>
  <Badge size="lg" color="orange">Cloud</Badge>
  <Badge size="lg" color="orange">مفتوح المصدر</Badge>
</div>

<div id="prerequisites">
  ## المتطلبات الأساسية
</div>

To successfully follow this guide, you'll need the following:

* A running ClickHouse Cloud service. If you don't have one yet, complete the [Create your first Cloud service](/get-started/quickstarts/create-your-first-service-on-cloud) quickstart first.

<div id="what-youll-build">
  ## ما ستبنيه
</div>

في هذا الدليل السريع، ستنشئ جدول **MergeTree** لتخزين سجلات مبيعات العقارات السكنية في المملكة المتحدة منذ عام 1995.
ستصمّم مخططًا بأنواع أعمدة مناسبة، وتختار قيمتَي `ORDER BY` و`PARTITION BY` بما يلائم البيانات، وتحمّل البيانات مباشرةً من S3، ثم تستعلم من `system.parts` لترى كيف ينظّم ClickHouse البيانات فعليًا على القرص.
وبنهاية هذا الدليل، ستفهم لماذا يُعد محرك MergeTree الأساس الذي تقوم عليه تقريبًا جميع جداول ClickHouse، وكيف تؤثر قرارات الفرز والتقسيم مباشرةً في أداء الاستعلامات.

<Steps titleSize="h3">
  <Step>
    ### افهم كيفية عمل MergeTree

    قبل كتابة أي SQL، من المفيد أن تعرف ما الذي يميز MergeTree عن جدول تقليدي في قاعدة بيانات.

    عندما تُدرِج بيانات في جدول MergeTree، لا يكتب ClickHouse الصفوف واحدًا تلو الآخر. وبدلًا من ذلك، يكتب **جزء بيانات** — وهو كتلة صغيرة من الصفوف، مرتبة ومضغوطة — مباشرةً على القرص. ثم يدمج ClickHouse هذه الأجزاء معًا في الخلفية بمرور الوقت. ومن هنا جاءت التسمية: *merge* + *tree*.

    يُرتَّب كل جزء بيانات وفق تعبير **`ORDER BY`** الخاص بالجدول. ويصبح ترتيب الفرز هذا **فهرس المفتاح الأساسي**، ما يتيح لـ ClickHouse تخطي كتل كبيرة من البيانات التي لا يحتاج إلى قراءتها أثناء تنفيذ query (ونسمي ذلك تقليم البيانات). وكلما كانت أعمدة `ORDER BY` أكثر انتقائية بالنسبة إلى استعلاماتك الأكثر شيوعًا، قلّت كمية البيانات التي يقرؤها ClickHouse.

    تتحكم ثلاثة بنود في كيفية تنظيم MergeTree لبياناتك:

    | البند          | ما الذي يفعله                                                                                                                                    |
    | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `ORDER BY`     | يرتّب البيانات فعليًا داخل كل جزء. ويحدد المفتاح الأساسي. وهو مطلوب.                                                                             |
    | `PARTITION BY` | يقسم البيانات إلى partitionات منفصلة، عادةً حسب نطاق زمني. ولا تُدمج الأجزاء من partitionات مختلفة معًا أبدًا، مما يتيح تقليم partitionات بسرعة. |
    | `PRIMARY KEY`  | تكون قيمته افتراضيًا `ORDER BY` ما لم تحدد صراحةً بادئة أقصر. ويُبنى منه الفهرس المتناثر.                                                        |

    ينبغي أن تكون الآن قادرًا على شرح العلاقة بين أجزاء البيانات، والمفتاح الأساسي، وأداء query في جدول MergeTree.
  </Step>

  <Step>
    ### معاينة البيانات المصدرية

    قبل إنشاء الجدول، افحص الملف المصدري باستخدام دالة الجدول `s3`. يتيح لك ذلك تنفيذ استعلام على S3 مباشرةً من دون كتابة أي بيانات إلى ClickHouse أولاً.

    شغّل ما يلي في وحدة تحكم SQL:

    ```sql theme={null}
    DESCRIBE s3(
    'https://learn-clickhouse.s3.us-east-2.amazonaws.com/uk_property_prices/uk_prices.csv.zst'
    );
    ```

    لاحظ أن كل عمود تقريبًا يُستدل عليه على أنه `Nullable(String)`. يقرأ ClickHouse ملف CSV خامًا، لذلك لا يعرف أنواع البيانات الفعلية — وهذا ما ستصححه عند تصميم مخطط الجدول في الخطوة التالية.

    استعرض بعض الصفوف:

    ```sql theme={null}
    SELECT *
    FROM s3(
    'https://learn-clickhouse.s3.us-east-2.amazonaws.com/uk_property_prices/uk_prices.csv.zst'
    )
    LIMIT 5;
    ```

    تحتوي مجموعة البيانات على مبيعات العقارات السكنية في إنجلترا وويلز المسجَّلة لدى HM Land Registry، بما في ذلك `id` للمعاملة، و`price` للبيع، و`date`، و`type` للعقار، وحقول العنوان، والمُعرِّفات الجغرافية. وستلاحظ أيضًا وجود عمودين في النهاية (`column15` و`column16`) فارغين — ويمكن تجاهلهما.

    تحقّق من ذلك بالتأكد من أنك ترى صفوفًا تتضمن أعمدة مثل `id` و`price` و`date` و`postcode` و`type` و`town` و`county`.
  </Step>

  <Step>
    ### صمّم وأنشئ جدول MergeTree الخاص بك

    أنشئ الآن جدولًا دائمًا ببنية مناسبة. وقد اختيرت أنواع الأعمدة أدناه بعناية:

    * يُستخدم `LowCardinality(String)` للأعمدة ذات العدد المحدود من القيم الفريدة (الرموز البريدية، وأسماء البلدات، وأسماء المقاطعات). ويستخدم أسلوب `dictionary encoding` داخليًا، ما يقلّل مساحة التخزين بشكل كبير ويحسّن الأداء عند التجميع والتصفية على هذه الأعمدة.
    * يرمّز `Enum8` العمودين `type` و`duration` كأعداد صحيحة صغيرة على القرص، مع الإبقاء على تسميات نصية سهلة القراءة في الاستعلامات. ويستخدم ملف CSV المصدر رموزًا من حرف واحد، لذا سنحوّلها أثناء `insert`.
    * ينشئ `PARTITION BY toYYYYMM(date)` partition واحدة لكل شهر تقويمي، ما يتيح لـ ClickHouse تخطي أشهر كاملة عندما تتضمّن عبارة `WHERE` عامل تصفية على `date`.
    * يرتّب `ORDER BY (postcode, addr1, addr2)` البيانات لدعم عمليات البحث السريعة حسب عنوان العقار، وهو نمط الوصول الأكثر طبيعية لمجموعة البيانات هذه.

    ```sql theme={null}
    CREATE TABLE uk_price_paid
    (
    price      UInt32,
    date       Date,
    postcode   LowCardinality(String),
    type       Enum8('terraced' = 1, 'semi-detached' = 2, 'detached' = 3, 'flat' = 4, 'other' = 0),
    is_new     UInt8,
    duration   Enum8('freehold' = 1, 'leasehold' = 2, 'unknown' = 0),
    addr1      String,
    addr2      String,
    street     LowCardinality(String),
    locality   LowCardinality(String),
    town       LowCardinality(String),
    district   LowCardinality(String),
    county     LowCardinality(String)
    )
    ENGINE = MergeTree
    PARTITION BY toYYYYMM(date)
    ORDER BY (postcode, addr1, addr2);
    ```

    تحقق من إنشاء الجدول بتشغيل:

    ```sql theme={null}
    SHOW CREATE TABLE uk_price_paid;
    ```

    انقر نقراً مزدوجاً على خلية النتيجة لفحص المخرجات الكاملة. لاحظ أنه رغم أنك حددت `ENGINE = MergeTree`، فإن ClickHouse Cloud أنشأت الجدول باستخدام `SharedMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}')`. هذا متوقع - إذ يحوّل Cloud تلقائياً `MergeTree` إلى `SharedMergeTree`، مما يضيف دعم التكرار والتخزين المشترك. ويظل السلوك وواجهة الاستعلام كما هما.
  </Step>

  <Step>
    ### تحميل البيانات من S3

    أدرِج مجموعة البيانات الكاملة بجلبها مباشرةً من دالة الجدول `s3()`. يقرأ ClickHouse الملف المضغوط من S3 بشكل متدفق ويكتبه إلى جدولك على هيئة أجزاء مرتبة.

    ```sql theme={null}
    INSERT INTO uk_price_paid
    SELECT
        toUInt32(price),
        date,
        postcode,
        transform(type, ['T', 'S', 'D', 'F', 'O'],
            ['terraced', 'semi-detached', 'detached', 'flat', 'other'], 'other') AS type,
        if(is_new = 'Y', 1, 0) AS is_new,
        transform(duration, ['F', 'L', 'U'],
            ['freehold', 'leasehold', 'unknown'], 'unknown') AS duration,
        addr1,
        addr2,
        street,
        locality,
        town,
        district,
        county
    FROM s3(
    'https://learn-clickhouse.s3.us-east-2.amazonaws.com/uk_property_prices/uk_prices.csv.zst'
    );
    ```

    نظرًا لأن ملف CSV المصدر يخزّن كل شيء كسلاسل نصية مع رموز أحادية الحرف (مثلًا `T` للمنازل المتلاصقة، و`F` للتملك الحر، و`Y`/`N` للبناء الجديد)، فإننا نستخدم `transform` لتحويلها إلى تسميات واضحة، ونستخدم `toUInt32`/`if` لتحويل الأعمدة الرقمية. وتُستبعَد الأعمدة `id` و`column15` و`column16` لأننا لا نحتاج إليها.

    سيستغرق ذلك دقيقة أو دقيقتين حسب حجم خدمتك. بعد اكتمال العملية، أكّد عدد الصفوف:

    ```sql theme={null}
    SELECT formatReadableQuantity(count())
    FROM uk_price_paid;
    ```

    يُفترض أن ترى أنه تم تحميل نحو 30 مليون صف.
  </Step>

  <Step>
    ### فحص الأجزاء باستخدام system.parts

    هنا تبدأ المكوّنات الداخلية لـ MergeTree بالظهور. يتتبّع جدول `system.parts` كل جزء بيانات على القرص لكل جدول MergeTree ضمن خدمتك.

    ```sql theme={null}
    SELECT
    partition,
    name,
    rows,
    bytes_on_disk,
    marks
    FROM system.parts
    WHERE table = 'uk_price_paid'
    AND active = true
    ORDER BY partition
    LIMIT 20;
    ```

    يمثل كل صف جزء بيانات نشطًا واحدًا. لاحظ ما يلي:

    * **`partition`** - قيمة `YYYYMM` المشتقة من تعبير `PARTITION BY`. تُفصل بيانات كل شهر على حدة.
    * **`name`** - يرمّز اسم الجزء إلى التقسيم، ونطاق أرقام الكتل، ومستوى الدمج (على سبيل المثال، تعني `199501_1_4_2` التقسيم `199501`، والكتل من 1 إلى 4، مع دمجه مرتين).
    * **`marks`** - عدد حبيبات الفهرس. تغطي كل حبيبة 8,192 صفًا افتراضيًا، ويخزّن فهرس المفتاح الأساسي مُدخلًا واحدًا لكل حبيبة. هذا الفهرس المتناثر هو ما يبقى في الذاكرة ويتيح تخطي البيانات بسرعة.
    * **`bytes_on_disk`** - يضغط ClickHouse كل جزء عمودًا بعمود باستخدام LZ4 افتراضيًا. قارِن ذلك بالحجم الخام لتقدير نسبة الضغط.

    لمعرفة العدد الإجمالي للأجزاء وإجمالي الحجم المضغوط لجدولك، شغّل:

    ```sql theme={null}
    SELECT
    count()          AS parts,
    sum(rows)        AS total_rows,
    formatReadableSize(sum(bytes_on_disk)) AS compressed_size
    FROM system.parts
    WHERE table = 'uk_price_paid'
    AND active = true;
    ```

    إذا شغّلت هذا `الاستعلام` مرة أخرى بعد فترة، فقد تلاحظ أن `عدد الأجزاء` قد انخفض. هذا هو *الدمج* في MergeTree أثناء العمل — إذ يدمج ClickHouse باستمرار الأجزاء الأصغر في أجزاء أكبر في الخلفية، مما يقلّل عدد الأجزاء. ويضمن عامل التصفية `active = true` أنك ترى فقط الأجزاء الحالية والمُدمجة، بدلًا من أي أجزاء أقدم لا تزال بانتظار التنظيف.
  </Step>

  <Step>
    ### استعلم عن البيانات وراقب سلوك المفتاح الأساسي

    الآن نفّذ بعض الاستعلامات التحليلية الحقيقية. أولًا، اعثر على أغلى عمليات البيع المسجّلة على الإطلاق:

    ```sql theme={null}
    SELECT
    addr1,
    addr2,
    town,
    county,
    price,
    date
    FROM uk_price_paid
    ORDER BY price DESC
    LIMIT 5;
    ```

    تحقّق من إحصاءات الاستعلام في SQL Console — ولاحظ أنه تمت قراءة جميع الصفوف وعددها 30,033,199. وبما أن `price` ليس جزءًا من مفتاح `ORDER BY`، فلا يمكن لـ ClickHouse استخدام الفهرس الأساسي لتخطي البيانات، لذا يجب إجراء فحص كامل للجدول.

    بعد ذلك، احسب متوسط سعر البيع حسب المقاطعة:

    ```sql theme={null}
    SELECT
    county,
    round(avg(price)) AS avg_price,
    count()           AS sales
    FROM uk_price_paid
    GROUP BY county
    ORDER BY avg_price DESC;
    ```

    مرة أخرى، تُقرأ الصفوف الـ 30,033,199 كلها — إذ إن `county` ليس ضمن `ORDER BY` أو `PARTITION BY`، لذا يفحص ClickHouse الجدول بأكمله.

    الآن شغّل استعلامًا يجمع بين التجميع و`ORDER BY` لديك. ونظرًا إلى أن البيانات مرتبة حسب `(postcode, addr1, addr2)`، فإن التصفية باستخدام بادئة الرمز البريدي تتيح لـ ClickHouse تخطي معظم الجدول. هنا نحسب متوسط سعر البيع لكل سنة للعقارات في منطقة الرمز البريدي `SW1A`:

    ```sql theme={null}
    SELECT
    toYear(date) AS year,
    round(avg(price)) AS avg_price,
    count() AS sales,
    min(price) AS cheapest,
    max(price) AS most_expensive
    FROM uk_price_paid
    WHERE postcode LIKE 'SW1A%'
    GROUP BY year
    ORDER BY year DESC;
    ```

    تحقق من إحصاءات الاستعلام في SQL Console بعد كل استعلام. ينبغي أن يقرأ التجميع المُرشَّح حسب `postcode` جزءًا فقط من صفوف الجدول، مما يوضح فاعلية فهرس المفتاح الأساسي. قارن ذلك بالاستعلامات السابقة التي تفحص نطاقًا أوسع — يوضح هذا الفرق سبب أهمية اختيار `ORDER BY` المناسب.
  </Step>
</Steps>

## الخطوات التالية

في هذا الدليل السريع، أنشأت جدول MergeTree من الصفر، وحمّلت 30 مليون سجل لعمليات بيع العقارات في المملكة المتحدة من S3، واستكشفت كيف ينظّم ClickHouse البيانات في أجزاء مرتبة وتقسيمات، ونفّذت استعلامات تُظهر قوة فهرس المفتاح الأساسي.

يُعدّ محرك MergeTree الأساس — ومن هنا يمكنك استكشاف المحركات المتخصصة المبنية عليه، أو التعرّف على كيفية توسيع العروض المُجسَّدة لهذا النمط بشكل أكبر.

اطّلع بعد ذلك على الأدلة السريعة التالية:

* [مقدمة إلى العروض المُجسَّدة](/ar/get-started/quickstarts/create-your-first-materialized-view)

أو تعمّق أكثر من خلال الوثائق المرجعية:

* [مرجع محرك MergeTree](/ar/reference/engines/table-engines/mergetree-family/mergetree)
* [مرجع system.parts](/ar/reference/system-tables/parts)
* [اختيار أنواع الأعمدة المناسبة](/ar/reference/data-types/index)

<Frame caption="Check out the ClickHouse academy for on-demand and live training">
  <a href="https://learn.clickhouse.com/" target="_blank">
    <img src="https://mintcdn.com/private-7c7dfe99-mintlify-8c05c8a2/GaEHa-fd8w_5w7tQ/images/academy.png?fit=max&auto=format&n=GaEHa-fd8w_5w7tQ&q=85&s=46be2d7327e98b07a2a4b1a422642a30" alt="ClickHouse Academy — Master ClickHouse with expert-designed training for every skill level" width="560" noZoom data-path="images/academy.png" />
  </a>
</Frame>

<div className="mt-8">
  <a href="/ar/get-started/quickstarts/home"><Badge size="lg" color="gray" icon="arrow-left">جميع الأدلة السريعة</Badge></a>
</div>
