التحليلات اللحظيةمستودعات البياناتالرصدالذكاء الاصطناعي/تعلّم الآلةCloudمفتوح المصدر
المتطلبات الأساسية
- A running ClickHouse Cloud service. If you don’t have one yet, complete the Create your first Cloud service quickstart first.
ما ستبنيه
ORDER BY وPARTITION BY بما يلائم البيانات، وتحمّل البيانات مباشرةً من S3، ثم تستعلم من system.parts لترى كيف ينظّم ClickHouse البيانات فعليًا على القرص.
وبنهاية هذا الدليل، ستفهم لماذا يُعد محرك MergeTree الأساس الذي تقوم عليه تقريبًا جميع جداول ClickHouse، وكيف تؤثر قرارات الفرز والتقسيم مباشرةً في أداء الاستعلامات.
1
افهم كيفية عمل MergeTree
قبل كتابة أي SQL، من المفيد أن تعرف ما الذي يميز MergeTree عن جدول تقليدي في قاعدة بيانات.عندما تُدرِج بيانات في جدول MergeTree، لا يكتب ClickHouse الصفوف واحدًا تلو الآخر. وبدلًا من ذلك، يكتب جزء بيانات — وهو كتلة صغيرة من الصفوف، مرتبة ومضغوطة — مباشرةً على القرص. ثم يدمج ClickHouse هذه الأجزاء معًا في الخلفية بمرور الوقت. ومن هنا جاءت التسمية: merge + tree.يُرتَّب كل جزء بيانات وفق تعبيرORDER BY الخاص بالجدول. ويصبح ترتيب الفرز هذا فهرس المفتاح الأساسي، ما يتيح لـ ClickHouse تخطي كتل كبيرة من البيانات التي لا يحتاج إلى قراءتها أثناء تنفيذ query (ونسمي ذلك تقليم البيانات). وكلما كانت أعمدة ORDER BY أكثر انتقائية بالنسبة إلى استعلاماتك الأكثر شيوعًا، قلّت كمية البيانات التي يقرؤها ClickHouse.تتحكم ثلاثة بنود في كيفية تنظيم MergeTree لبياناتك:ينبغي أن تكون الآن قادرًا على شرح العلاقة بين أجزاء البيانات، والمفتاح الأساسي، وأداء query في جدول MergeTree.
2
معاينة البيانات المصدرية
قبل إنشاء الجدول، افحص الملف المصدري باستخدام دالة الجدولs3. يتيح لك ذلك تنفيذ استعلام على S3 مباشرةً من دون كتابة أي بيانات إلى ClickHouse أولاً.شغّل ما يلي في وحدة تحكم SQL:Nullable(String). يقرأ ClickHouse ملف CSV خامًا، لذلك لا يعرف أنواع البيانات الفعلية — وهذا ما ستصححه عند تصميم مخطط الجدول في الخطوة التالية.استعرض بعض الصفوف:id للمعاملة، وprice للبيع، وdate، وtype للعقار، وحقول العنوان، والمُعرِّفات الجغرافية. وستلاحظ أيضًا وجود عمودين في النهاية (column15 وcolumn16) فارغين — ويمكن تجاهلهما.تحقّق من ذلك بالتأكد من أنك ترى صفوفًا تتضمن أعمدة مثل id وprice وdate وpostcode وtype وtown وcounty.3
صمّم وأنشئ جدول MergeTree الخاص بك
أنشئ الآن جدولًا دائمًا ببنية مناسبة. وقد اختيرت أنواع الأعمدة أدناه بعناية:- يُستخدم
LowCardinality(String)للأعمدة ذات العدد المحدود من القيم الفريدة (الرموز البريدية، وأسماء البلدات، وأسماء المقاطعات). ويستخدم أسلوبdictionary encodingداخليًا، ما يقلّل مساحة التخزين بشكل كبير ويحسّن الأداء عند التجميع والتصفية على هذه الأعمدة. - يرمّز
Enum8العمودينtypeوdurationكأعداد صحيحة صغيرة على القرص، مع الإبقاء على تسميات نصية سهلة القراءة في الاستعلامات. ويستخدم ملف CSV المصدر رموزًا من حرف واحد، لذا سنحوّلها أثناءinsert. - ينشئ
PARTITION BY toYYYYMM(date)partition واحدة لكل شهر تقويمي، ما يتيح لـ ClickHouse تخطي أشهر كاملة عندما تتضمّن عبارةWHEREعامل تصفية علىdate. - يرتّب
ORDER BY (postcode, addr1, addr2)البيانات لدعم عمليات البحث السريعة حسب عنوان العقار، وهو نمط الوصول الأكثر طبيعية لمجموعة البيانات هذه.
ENGINE = MergeTree، فإن ClickHouse Cloud أنشأت الجدول باستخدام SharedMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}'). هذا متوقع - إذ يحوّل Cloud تلقائياً MergeTree إلى SharedMergeTree، مما يضيف دعم التكرار والتخزين المشترك. ويظل السلوك وواجهة الاستعلام كما هما.4
تحميل البيانات من S3
أدرِج مجموعة البيانات الكاملة بجلبها مباشرةً من دالة الجدولs3(). يقرأ ClickHouse الملف المضغوط من S3 بشكل متدفق ويكتبه إلى جدولك على هيئة أجزاء مرتبة.T للمنازل المتلاصقة، وF للتملك الحر، وY/N للبناء الجديد)، فإننا نستخدم transform لتحويلها إلى تسميات واضحة، ونستخدم toUInt32/if لتحويل الأعمدة الرقمية. وتُستبعَد الأعمدة id وcolumn15 وcolumn16 لأننا لا نحتاج إليها.سيستغرق ذلك دقيقة أو دقيقتين حسب حجم خدمتك. بعد اكتمال العملية، أكّد عدد الصفوف:5
فحص الأجزاء باستخدام system.parts
هنا تبدأ المكوّنات الداخلية لـ MergeTree بالظهور. يتتبّع جدولsystem.parts كل جزء بيانات على القرص لكل جدول MergeTree ضمن خدمتك.partition- قيمةYYYYMMالمشتقة من تعبيرPARTITION BY. تُفصل بيانات كل شهر على حدة.name- يرمّز اسم الجزء إلى التقسيم، ونطاق أرقام الكتل، ومستوى الدمج (على سبيل المثال، تعني199501_1_4_2التقسيم199501، والكتل من 1 إلى 4، مع دمجه مرتين).marks- عدد حبيبات الفهرس. تغطي كل حبيبة 8,192 صفًا افتراضيًا، ويخزّن فهرس المفتاح الأساسي مُدخلًا واحدًا لكل حبيبة. هذا الفهرس المتناثر هو ما يبقى في الذاكرة ويتيح تخطي البيانات بسرعة.bytes_on_disk- يضغط ClickHouse كل جزء عمودًا بعمود باستخدام LZ4 افتراضيًا. قارِن ذلك بالحجم الخام لتقدير نسبة الضغط.
الاستعلام مرة أخرى بعد فترة، فقد تلاحظ أن عدد الأجزاء قد انخفض. هذا هو الدمج في MergeTree أثناء العمل — إذ يدمج ClickHouse باستمرار الأجزاء الأصغر في أجزاء أكبر في الخلفية، مما يقلّل عدد الأجزاء. ويضمن عامل التصفية active = true أنك ترى فقط الأجزاء الحالية والمُدمجة، بدلًا من أي أجزاء أقدم لا تزال بانتظار التنظيف.6
استعلم عن البيانات وراقب سلوك المفتاح الأساسي
الآن نفّذ بعض الاستعلامات التحليلية الحقيقية. أولًا، اعثر على أغلى عمليات البيع المسجّلة على الإطلاق:price ليس جزءًا من مفتاح ORDER BY، فلا يمكن لـ ClickHouse استخدام الفهرس الأساسي لتخطي البيانات، لذا يجب إجراء فحص كامل للجدول.بعد ذلك، احسب متوسط سعر البيع حسب المقاطعة:county ليس ضمن ORDER BY أو PARTITION BY، لذا يفحص ClickHouse الجدول بأكمله.الآن شغّل استعلامًا يجمع بين التجميع وORDER BY لديك. ونظرًا إلى أن البيانات مرتبة حسب (postcode, addr1, addr2)، فإن التصفية باستخدام بادئة الرمز البريدي تتيح لـ ClickHouse تخطي معظم الجدول. هنا نحسب متوسط سعر البيع لكل سنة للعقارات في منطقة الرمز البريدي SW1A:postcode جزءًا فقط من صفوف الجدول، مما يوضح فاعلية فهرس المفتاح الأساسي. قارن ذلك بالاستعلامات السابقة التي تفحص نطاقًا أوسع — يوضح هذا الفرق سبب أهمية اختيار ORDER BY المناسب.