Skip to main content
يتميز هذا المحرك بما يلي:
  • يتيح الكتابة السريعة لحالات الكائنات التي تتغير باستمرار.
  • يحذف حالات الكائنات القديمة في الخلفية. وهذا يقلل حجم التخزين بشكل كبير.
راجع قسم طي لمزيد من التفاصيل. يرث هذا المحرك من MergeTree ويضيف منطق طي الصفوف إلى خوارزمية دمج أجزاء البيانات. يؤدي VersionedCollapsingMergeTree الغرض نفسه الذي يؤديه CollapsingMergeTree، لكنه يستخدم خوارزمية طي مختلفة تتيح إدراج البيانات بأي ترتيب باستخدام عدة خيوط. وعلى وجه الخصوص، يساعد العمود Version على طي الصفوف بشكل صحيح حتى إذا أُدرجت بترتيب غير صحيح. في المقابل، لا يتيح CollapsingMergeTree إلا الإدراج المتتالي الصارم.

إنشاء جدول

للاطلاع على وصف معلمات الاستعلام، راجع وصف الاستعلام.

معلمات المحرك

بنود الاستعلام

عند إنشاء جدول VersionedCollapsingMergeTree، تكون البنود نفسها مطلوبة كما عند إنشاء جدول MergeTree.

الاختزال

البيانات

لنفترض أنك تحتاج إلى حفظ بيانات تتغير باستمرار لكائن معيّن. من المنطقي أن يكون لهذا الكائن صف واحد، وأن يُحدَّث هذا الصف كلما طرأت تغييرات. لكن عملية التحديث مكلفة وبطيئة بالنسبة إلى نظام إدارة قواعد البيانات (DBMS)، لأنها تتطلب إعادة كتابة البيانات في التخزين. لذلك لا يكون التحديث مناسبًا إذا كنت بحاجة إلى كتابة البيانات بسرعة، لكن يمكنك بدلاً من ذلك كتابة التغييرات الخاصة بالكائن بشكل تسلسلي كما يلي. استخدم العمود Sign عند كتابة الصف. إذا كانت قيمة Sign = 1 فهذا يعني أن الصف يمثّل حالة لكائن ما (لنسمّه صف “الحالة”). وإذا كانت قيمة Sign = -1 فهذا يشير إلى إلغاء حالة لكائن له السمات نفسها (لنسمّه صف “الإلغاء”). واستخدم أيضًا العمود Version، الذي ينبغي أن يميّز كل حالة من حالات الكائن برقم مستقل. على سبيل المثال، لنفترض أننا نريد حساب عدد الصفحات التي زارها المستخدمون على موقع ما، والمدة التي قضوها هناك. في لحظة زمنية معيّنة، نكتب الصف التالي الذي يمثّل حالة نشاط المستخدم:
في مرحلة لاحقة، نسجّل التغيير في نشاط المستخدم وندوّنه في الصفّين التاليين.
يلغي الصف الأول الحالة السابقة للكائن (المستخدم). ويجب أن ينسخ جميع حقول الحالة المُلغاة باستثناء Sign. يحتوي الصف الثاني على الحالة الحالية. وبما أننا نحتاج فقط إلى أحدث حالة لنشاط المستخدم، فإن الصفوف
يمكن حذفها، مما يؤدي إلى طيّ الحالة غير الصالحة (القديمة) للكائن. ويقوم VersionedCollapsingMergeTree بذلك أثناء دمج أجزاء البيانات. لمعرفة سبب حاجتنا إلى صفّين لكل تغيير، راجع Algorithm. ملاحظات حول الاستخدام
  1. يجب أن يتذكر البرنامج الذي يكتب البيانات حالة الكائن حتى يتمكن من إلغائها. يجب أن يحتوي السطر “إلغاء” على نسخ من حقول المفتاح الأساسي، وإصدار السطر “حالة”، وقيمة Sign المعاكسة. يزيد ذلك الحجم الأولي للتخزين، لكنه يتيح كتابة البيانات بسرعة.
  2. تؤدي المصفوفات الطويلة والمتزايدة في الأعمدة إلى تقليل كفاءة المحرك بسبب العبء الواقع على عمليات الكتابة. وكلما كانت البيانات أبسط، كانت الكفاءة أفضل.
  3. تعتمد نتائج SELECT بدرجة كبيرة على اتساق سجل تغييرات الكائن. كن دقيقًا عند إعداد البيانات للإدراج. فقد تحصل على نتائج غير متوقعة مع البيانات غير المتسقة، مثل القيم السالبة لمقاييس غير سالبة مثل عمق الجلسة.

الخوارزمية

عندما يدمج ClickHouse أجزاء البيانات، يحذف كل زوج من الصفوف لهما المفتاح الأساسي نفسه والإصدار نفسه وتكون قيمة Sign فيهما مختلفة. ولا يهم ترتيب الصفوف. عندما يُدرِج ClickHouse البيانات، فإنه يرتب الصفوف حسب المفتاح الأساسي. وإذا لم يكن العمود Version ضمن المفتاح الأساسي، يضيفه ClickHouse ضمنيًا إلى المفتاح الأساسي باعتباره الحقل الأخير ويستخدمه في الترتيب.

اختيار البيانات

لا يضمن ClickHouse أن تكون جميع الصفوف التي لها المفتاح الأساسي نفسه في جزء البيانات الناتج نفسه، أو حتى على الخادم الفعلي نفسه. وينطبق ذلك سواء عند كتابة البيانات أو عند الدمج اللاحق لأجزاء البيانات. بالإضافة إلى ذلك، يعالج ClickHouse استعلامات SELECT باستخدام عدة خيوط تنفيذ، ولا يمكنه التنبؤ بترتيب الصفوف في النتيجة. وهذا يعني أن التجميع مطلوب إذا كانت هناك حاجة إلى الحصول على بيانات “مطوية” بالكامل من جدول VersionedCollapsingMergeTree. لإتمام الطي، اكتب استعلامًا يتضمن عبارة GROUP BY ودوال تجميع تراعي الإشارة. على سبيل المثال، لحساب الكمية، استخدم sum(Sign) بدلًا من count(). ولحساب مجموع قيمةٍ ما، استخدم sum(Sign * x) بدلًا من sum(x)، وأضف HAVING sum(Sign) > 0. يمكن حساب count وsum وavg بهذه الطريقة. ويمكن حساب uniq إذا كان للكائن حالة واحدة غير مطوية على الأقل. أما min وmax فلا يمكن حسابهما لأن VersionedCollapsingMergeTree لا يحتفظ بسجل قيم الحالات المطوية. إذا كنت بحاجة إلى استخراج البيانات مع “الطي” ولكن من دون تجميع (على سبيل المثال، للتحقق مما إذا كانت هناك صفوف تتطابق أحدث قيمها مع شروط معينة)، فيمكنك استخدام المعدِّل FINAL مع عبارة FROM. هذا النهج غير فعّال ويجب عدم استخدامه مع الجداول الكبيرة.

مثال للاستخدام

بيانات المثال:
إنشاء الجدول:
إدخال البيانات:
نستخدم استعلامَي INSERT لإنشاء جزأَي بيانات مختلفين. وإذا أدرجنا البيانات باستعلام واحد، فسينشئ ClickHouse جزء بيانات واحدًا ولن ينفّذ أي عملية دمج. جلب البيانات:
ماذا نرى هنا، وأين الأجزاء التي تم طيّها؟ لقد أنشأنا جزأين من البيانات باستخدام استعلامَي INSERT. نُفِّذ استعلام SELECT على خيطَي تنفيذ، وكانت النتيجة ترتيبًا عشوائيًا للصفوف. لم يحدث الطي لأن أجزاء البيانات لم تُدمج بعد. يدمج ClickHouse أجزاء البيانات في وقت غير معلوم لا يمكننا التنبؤ به. ولهذا نحتاج إلى التجميع:
إذا لم نكن بحاجة إلى التجميع وأردنا فرض عملية الطيّ، يمكننا استخدام المُعدِّل FINAL مع عبارة FROM.
هذه طريقة غير فعّالة للغاية لاستخراج البيانات. لا تستخدمها مع الجداول الكبيرة.
آخر تعديل في ٢٣ يوليو ٢٠٢٦