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

# إزالة تكرار عمليات الإدراج عند إعادة المحاولة

> منع تكرار البيانات عند إعادة محاولة عمليات الإدراج

قد تفشل عمليات الإدراج أحيانًا بسبب أخطاء مثل انتهاء المهلة. وعند فشلها، قد تكون البيانات قد أُدرجت بنجاح أو لا. يوضح هذا الدليل كيفية عمل إزالة التكرار عند إعادة محاولة الإدراج، بحيث لا تُدرج البيانات نفسها أكثر من مرة.

عند إعادة محاولة الإدراج، يحاول ClickHouse التحقق مما إذا كانت البيانات قد أُدرجت بنجاح بالفعل. وإذا وُسِمت البيانات المُدرجة على أنها مكررة، فلن يُدرجها ClickHouse في الجدول الوجهة. ومع ذلك، سيظل المستخدم يتلقى حالة نجاح للعملية كما لو كانت البيانات قد أُدرجت بشكل طبيعي.

تشمل إزالة التكرار عمليات الإدراج المتزامنة، وعمليات الإدراج غير المتزامنة، واستعلامات `INSERT ... SELECT`. يتحكم إعداد واحد، وهو `deduplicate_insert`، في عمليات الإدراج المتزامنة وغير المتزامنة. تتطلب `INSERT ... SELECT` عناية إضافية ولها إعداد خاص بها. راجع [الإعدادات التي تتحكم في إزالة تكرار عمليات الإدراج](#settings-that-control-insert-deduplication).

<div id="limitations">
  ## القيود
</div>

<div id="uncertain-insert-status">
  ### حالة الإدراج غير المؤكدة
</div>

يجب على المستخدم إعادة محاولة عملية الإدراج حتى تنجح. وإذا فشلت جميع المحاولات، يصبح من المستحيل تحديد ما إذا كانت البيانات قد أُدرجت أم لا. وعندما تكون العروض المادية معنية، لا يكون واضحًا أيضًا في أي الجداول ربما ظهرت البيانات. وقد تكون العروض المادية غير متزامنة مع الجدول المصدر.

<div id="deduplication-window-limit">
  ### حد نافذة إزالة التكرار
</div>

إذا جرت أكثر من `*_deduplication_window` عملية إدراج أخرى أثناء تسلسل إعادة المحاولة، فقد لا تعمل إزالة التكرار كما هو مقصود. في هذه الحالة، قد تُدرَج البيانات نفسها عدة مرات.

<div id="settings-that-control-insert-deduplication">
  ## الإعدادات التي تتحكم في إزالة التكرار
</div>

لا يزيل ClickHouse تكرار عملية إدراج إلا عند استيفاء الشرطين التاليين:

1. أن يحتفظ الجدول الوجهة بسجل لإزالة التكرار. هذا إعداد على مستوى الجدول.
2. أن تكون إزالة التكرار مفعّلة للاستعلام. هذا إعداد على مستوى الاستعلام.

<div id="insert-deduplication-for-tables">
  ### إعدادات على مستوى الجدول
</div>

**لا تدعم إزالة التكرار عند الإدراج سوى محرّكات `*MergeTree`.**

بالنسبة إلى محرّكات `*ReplicatedMergeTree`، يكون سجل إزالة التكرار مفعّلًا افتراضيًا، ويتحكم فيه الإعدادان [`replicated_deduplication_window`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window) و[`replicated_deduplication_window_seconds`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window_seconds). أما في محرّكات `*MergeTree` غير المكرّرة، فيتحكم في السجل الإعداد [`non_replicated_deduplication_window`](/ar/reference/settings/merge-tree-settings/other#non_replicated_deduplication_window)، الذي تكون قيمته `0` افتراضيًا. لذلك، لا يزيل جدول `MergeTree` العادي أي تكرار حتى تضبط تلك النافذة على قيمة موجبة.

تحدّد الإعدادات أعلاه معلمات سجل إزالة التكرار للجدول. ويخزّن سجل إزالة التكرار عددًا محدودًا من `block_id`s\`، وهي التي تحدد آلية عمل إزالة التكرار (انظر أدناه).

<Note>
  يُعدّ كل من [`replicated_deduplication_window_for_async_inserts`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window_for_async_inserts) و[`replicated_deduplication_window_seconds_for_async_inserts`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window_seconds_for_async_inserts) إعدادين قديمين. تشترك عمليات الإدراج المتزامنة وغير المتزامنة الآن في سجل إزالة تكرار واحد، لذا يتحكم `replicated_deduplication_window` في كليهما. كانت الإعدادات القديمة تحدّ فقط دليل ClickHouse Keeper القديم، وهو أمر مهم أثناء ترقية تدريجية.
</Note>

<div id="query-level-insert-deduplication">
  ### إعدادات على مستوى الاستعلام
</div>

| الإعداد                                                                                                                                                  | ينطبق على                                    | القيمة الافتراضية      | الغرض                                                                  |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ---------------------- | ---------------------------------------------------------------------- |
| [`deduplicate_insert`](/ar/reference/settings/session-settings/deduplicate-insert#deduplicate_insert)                                                    | كل `INSERT`، سواء كان متزامنًا أو غير متزامن | `enable`               | المفتاح الرئيسي لإزالة تكرار عمليات الإدراج                            |
| [`deduplicate_insert_select`](/ar/reference/settings/session-settings/deduplicate-insert#deduplicate_insert_select)                                      | `INSERT ... SELECT`                          | `enable_when_possible` | يحدد الإجراء المتخذ عندما تكون نتيجة `SELECT` غير قابلة لإعادة الإنتاج |
| [`insert_deduplication_token`](/ar/reference/settings/session-settings/insert#insert_deduplication_token)                                                | كل `INSERT`                                  | `''`                   | يحدد عملية الإدراج باستخدام سلسلة يوفّرها المستخدم بدلًا من البيانات   |
| [`deduplicate_blocks_in_dependent_materialized_views`](/ar/reference/settings/session-settings/other#deduplicate_blocks_in_dependent_materialized_views) | الجداول التابعة للعروض المادية               | `1`                    | يوسّع إزالة التكرار لتشمل وجهات العروض المادية التابعة                 |

يقبل `deduplicate_insert` ثلاث قيم:

* `enable` — تُفعّل إزالة التكرار لاستعلام `INSERT`.
* `disable` — تُعطّل إزالة التكرار لاستعلام `INSERT`.
* `backward_compatible_choice` — يُفوَّض القرار إلى الإعدادات القديمة `insert_deduplicate` (عمليات الإدراج المتزامنة) و`async_insert_deduplicate` (عمليات الإدراج غير المتزامنة).

لاحظ أن الاستعلام الذي يعمل مع `deduplicate_insert = disable` لا يكتب أي قيم `block_id` لكتله. ولا يمكن إزالة تكرار هذه البيانات لاحقًا، حتى إذا أعدت محاولة الإدراج باستخدام `deduplicate_insert = enable`. وينطبق الأمر نفسه عندما لا يحتفظ جدول الوجهة بسجل إزالة التكرار: فلا يُسجَّل شيء، وبالتالي لا يمكن مطابقة أي شيء عند إعادة المحاولة.

<div id="precedence">
  ### الأسبقية
</div>

1. بالنسبة إلى استعلام `INSERT ... SELECT`، تكون الأولوية لـ `deduplicate_insert_select`. راجع [إزالة التكرار لـ INSERT ... SELECT](#deduplication-for-insert-select).
2. بالنسبة إلى جميع عمليات `INSERT` الأخرى، تكون الأولوية لـ `deduplicate_insert`.
3. لا تُقرأ `insert_deduplicate` و`async_insert_deduplicate` إلا عندما تكون قيمة `deduplicate_insert` هي `backward_compatible_choice`.

<div id="legacy-and-obsolete-settings">
  ### الإعدادات الموروثة والمتقادمة
</div>

| الإعداد                                                                                                     | الحالة                                                                                | استخدم بدلًا منه            |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | --------------------------- |
| [`insert_deduplicate`](/ar/reference/settings/session-settings/insert#insert_deduplicate)                   | موروث. لا يُقرأ إلا عندما تكون قيمة `deduplicate_insert = backward_compatible_choice` | `deduplicate_insert`        |
| [`async_insert_deduplicate`](/ar/reference/settings/session-settings/async-insert#async_insert_deduplicate) | موروث. لا يُقرأ إلا عندما تكون قيمة `deduplicate_insert = backward_compatible_choice` | `deduplicate_insert`        |
| `insert_select_deduplicate`                                                                                 | متقادم. ليس له أي تأثير                                                               | `deduplicate_insert_select` |
| `update_insert_deduplication_token_in_dependent_materialized_views`                                         | متقادم. ليس له أي تأثير                                                               | —                           |

<Warning>
  اعتبارًا من الإصدار 26.2، تكون القيمة الافتراضية لـ `deduplicate_insert` هي `enable`. لذا، لم يعد ضبط `insert_deduplicate = 0` يعطّل إزالة التكرار بمفرده. لتعطيل إزالة التكرار، اضبط `deduplicate_insert = disable`.
</Warning>

غيّر الإصدار 26.2 أيضًا القيم الافتراضية لـ `async_insert` و`deduplicate_blocks_in_dependent_materialized_views` إلى مفعّلة. يتحكم إعداد [`compatibility`](/ar/reference/settings/session-settings/compatibility#compatibility) في الإعدادات الثلاثة جميعها. إذا ضبطت `compatibility` على إصدار أقدم من `26.2`، فستحتفظ هذه الإعدادات بقيمها الافتراضية القديمة: تصبح قيمة `deduplicate_insert` هي `backward_compatible_choice`، ما يُحيل القرار إلى `insert_deduplicate` و`async_insert_deduplicate`. ويُطبَّق دائمًا أي إعداد تعيّنه صراحةً، ولا يتأثر مطلقًا بـ `compatibility`.

<div id="how-insert-deduplication-works">
  ## كيف تعمل إزالة التكرار عند الإدراج
</div>

عند إدراج البيانات في ClickHouse، تُقسَّم البيانات إلى كتل استنادًا إلى عدد الصفوف والبايتات.

بالنسبة إلى الجداول التي تستخدم محركات `*MergeTree`، يُخصَّص لكل كتلة `block_id` فريد، وهو `hash` لبيانات تلك الكتلة. ويُستخدم `block_id` هذا كمفتاح فريد لعملية الإدراج. وإذا عُثر على `block_id` نفسه في سجل إزالة التكرار، تُعتبر الكتلة مكررة ولا تُدرج في الجدول.

يعمل هذا النهج جيدًا عندما تحتوي عمليات الإدراج على بيانات مختلفة. ولكن إذا أُدرجت البيانات نفسها عدة مرات عن قصد، فستحتاج إلى استخدام الإعداد `insert_deduplication_token` للتحكم في عملية إزالة التكرار. يتيح لك هذا الإعداد تحديد رمز مميز فريد لكل عملية إدراج، ويستخدم ClickHouse هذا الرمز لتحديد ما إذا كانت البيانات مكررة. يتمتع `insert_deduplication_token` بأولوية أعلى: لا يستخدم ClickHouse قيمة `hash` للبيانات عند توفير الرمز.

بالنسبة إلى استعلامات `INSERT ... VALUES`، يكون تقسيم البيانات المُدرجة إلى كتل حتميًا ويتحدد بواسطة الإعدادات. لذلك، ينبغي إعادة محاولة الإدراج باستخدام قيم الإعدادات نفسها التي استُخدمت في العملية الأولى.

<div id="deduplication-for-insert-select">
  ## إزالة التكرار في `INSERT ... SELECT`
</div>

بالنسبة إلى استعلامات `INSERT ... SELECT`، يجب أن يُرجع جزء `SELECT` البيانات نفسها وبالترتيب نفسه في كل محاولة. وإلا فستختلف الكتل و`block_id`s، ولن يُتعرّف على إعادة المحاولة باعتبارها مكررة.

لا يستطيع ClickHouse التحقق من عدم تغيّر البيانات المصدر، لكنه يستطيع التحقق مما إذا كان الاستعلام نفسه ينتج نتيجة قابلة لإعادة الإنتاج. يُعامل `SELECT` على أنه **مستقر** عند استيفاء الشرطين التاليين:

* أن يتضمن الاستعلام عبارة `ORDER BY ALL`. لا يُتعرّف إلا على الصيغة الحرفية `ORDER BY ALL`. أما `ORDER BY <expressions>` العادي فلا يُتعرّف عليه، ولا يكون `UNION` من عمليتي `SELECT` أو أكثر مستقرًا أبدًا.
* أن ينتهي مسار القراءة بتدفق واحد.

يُعدّ `insert_deduplication_token` غير الفارغ بديلًا مكافئًا للاستقرار، لأن الرمز، وليس البيانات، هو ما يعرّف عملية الإدراج في هذه الحالة.

يحدد الإعداد `deduplicate_insert_select` الإجراء المتبع:

| القيمة                           | السلوك                                                                                                                                                                                 |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enable_when_possible` (افتراضي) | أزل التكرار عندما يكون `SELECT` مستقرًا أو عند تعيين رمز. وإلا، فتجاوز إزالة التكرار واكتب رسالة في سجل الخادم.                                                                        |
| `force_enable`                   | أزل التكرار دائمًا. إذا لم يكن `SELECT` مستقرًا ولم يُعيَّن رمز، فأطلق الاستثناء `DEDUPLICATION_IS_NOT_POSSIBLE`.                                                                      |
| `enable_even_for_bad_queries`    | أزل التكرار بغض النظر عن الاستقرار. يُحتفَظ به للتوافق مع الإصدارات السابقة. مع `SELECT` غير مستقر، لا يُتعرّف عادةً على إعادة المحاولة باعتبارها مكررة، لذا يُفضّل استخدام قيمة أخرى. |
| `disable`                        | لا تزل تكرار `INSERT ... SELECT` أبدًا.                                                                                                                                                |

يحترم كل من `enable_when_possible` و`enable_even_for_bad_queries` أيضًا `deduplicate_insert`: إذا كانت قيمته `disable`، فلن يُزال تكرار الاستعلام. يتجاوز `force_enable` قيمة `deduplicate_insert`.

ضع في اعتبارك أنه قد يُحدَّث الجدول المحدد بين عمليات إعادة المحاولة. عندها يتصرف المساران بصورة متعاكسة:

* بدون `insert_deduplication_token`، تُحسب `block_id`s من البيانات. تؤدي النتيجة المتغيرة إلى `block_id`s مختلفة، فلا تحدث إزالة التكرار، وتُدرج إعادة المحاولة البيانات الجديدة فوق أي بيانات كتبتها المحاولة الأولى بالفعل.
* مع `insert_deduplication_token`، يعرّف الرمز وحده عملية الإدراج. يُتعرّف على إعادة المحاولة باعتبارها مكررة وتُسقط، حتى لو كانت ستدرج بيانات مختلفة.

اختر المسار الذي يتوافق مع المعنى الذي تريده لإعادة المحاولة. كذلك، عند إدراج كميات كبيرة من البيانات، قد يتجاوز عدد الكتل نافذة سجل إزالة التكرار، وعندها لن يعرف ClickHouse أن عليه إزالة تكرار الكتل.

<div id="deduplication-for-asynchronous-inserts">
  ## إزالة التكرار لعمليات الإدراج غير المتزامنة
</div>

تُزال تكرارات عمليات الإدراج غير المتزامنة ([`async_insert`](/ar/reference/settings/session-settings/async-insert#async_insert)، وهي مفعّلة افتراضيًا منذ الإصدار 26.2) عند إعادة المحاولة بالطريقة نفسها المتبعة لعمليات الإدراج المتزامنة. ويتحكم `deduplicate_insert` في كليهما، لذا لا حاجة إلى مفتاح منفصل.

يشترك نوعا الإدراج أيضًا في سجل واحد لإزالة التكرار، ويحسبان `block_id`s بالطريقة نفسها. لذلك، يمكنك تبديل العميل بين عمليات الإدراج المتزامنة وغير المتزامنة دون التأثير في إزالة التكرار، وتبقى إعادة المحاولة المُرسلة في أحد الوضعين معروفة كتكرار لمحاولة أُرسلت في الوضع الآخر. كما يبقى نقل حمل عمل من عمليات الإدراج المتزامنة إلى غير المتزامنة آمنًا في جدول يعتمد على إزالة التكرار.

<Note>
  قبل الإصدار 26.2، كانت إزالة تكرار عمليات الإدراج غير المتزامنة معطّلة افتراضيًا، وكان يتحكم فيها `async_insert_deduplicate`. ولا يُقرأ هذا الإعداد الآن إلا عندما تكون قيمة `deduplicate_insert` هي `backward_compatible_choice`.
</Note>

<div id="asynchronous-insert-deduplication-granularity">
  ### دقة إزالة التكرار
</div>

يجمع الخادم عدة عمليات إدراج غير متزامنة في دفعة واحدة ويكتب هذه الدفعة في جزء واحد أو أكثر، بواقع جزء واحد على الأقل لكل قيمة مميزة لمفتاح التقسيم. تعمل إزالة التكرار على مستوى استعلام المستخدم، وليس على مستوى الدفعة:

* يضيف كل استعلام في قائمة الانتظار رمزاً واحداً لإزالة التكرار إلى الدفعة.
* يكون الرمز إما قيمة `insert_deduplication_token` إذا وفّرها الاستعلام، أو hash للصفوف التي أضافها هذا الاستعلام.
* لا يؤثر التجميع في دفعات في الرموز، كما لا يؤثر `insert_deduplication_token` في كيفية تجميع الاستعلامات ضمن دفعات.

ينتج عن ذلك نتيجتان:

* إذا كان أحد الاستعلامات في دفعة مكرراً، فإن ClickHouse يزيل صفوف ذلك الاستعلام فقط. وتُدرج بقية الدفعة بشكل طبيعي. ولا يُتخطى الجزء بالكامل إلا إذا أُزيلت جميع صفوفه.
* إذا حمل استعلامان في الدفعة نفسها الرمز ذاته، يُسقط الاستعلام الثاني قبل كتابة الجزء. ينطبق ذلك على كل تقسيم على حدة: فإذا كتب الاستعلامان صفوفاً في تقسيمات مختلفة، يُحتفظ بكليهما.

تحصي الأحداث `DuplicatedAsyncInserts` و`SelfDuplicatedAsyncInserts` في [`system.events`](/ar/reference/system-tables/events) هاتين الحالتين.

<div id="asynchronous-inserts-and-materialized-views">
  ### عمليات الإدراج غير المتزامنة والعروض المادية
</div>

تعمل إزالة التكرار في عمليات الإدراج غير المتزامنة بالتزامن مع العروض المادية التابعة. القاعدة بسيطة: كتلة واحدة تدخل، وكتلة واحدة تخرج. إذا حوّل الاستعلام الداخلي لعرض كتلة إدخال واحدة إلى كتلة إخراج واحدة، تعمل إزالة التكرار. أما إذا أصدر العرض كتلة ثانية، فيُطلق ClickHouse استثناء `NOT_IMPLEMENTED`.

يصدر العرض كتلة ثانية عندما لا يعود الإخراج ضمن كتلة واحدة. يحدد [`max_block_size`](/ar/reference/settings/session-settings/max#max_block_size) عدد الصفوف التي يمكن أن تتسع لها الكتلة. لا تضيف تحويلات الأعمدة أو التصفية أو التجميع صفوفًا، لذا تبقى دائمًا ضمن كتلة واحدة. يمكن أن يضيف `JOIN` صفوفًا. ويعمل ما دامت النتيجة لا تتجاوز `max_block_size`، ويفشل عند تجاوزها.

للإدراج عبر عرض يصدر أكثر من كتلة واحدة، عيّن `deduplicate_blocks_in_dependent_materialized_views = 0` أو استخدم عمليات الإدراج المتزامنة.

<div id="insert-deduplication-with-materialized-views">
  ## إزالة التكرار عند الإدراج مع العروض المادية
</div>

عندما يحتوي جدول على عرض مادي واحد أو أكثر، تُدرَج البيانات أيضًا في وجهة تلك العروض مع التحويلات المحددة. كما يُزال تكرار البيانات المُحوَّلة عند إعادة المحاولة أيضًا. ويُجري ClickHouse إزالة التكرار للعروض المادية بالطريقة نفسها التي يُجري بها إزالة التكرار للبيانات المُدرجة في الجدول الهدف.

يمكنك التحكم في هذه العملية باستخدام الإعدادات التالية للجدول المصدر:

* [`replicated_deduplication_window`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window)
* [`replicated_deduplication_window_seconds`](/ar/reference/settings/merge-tree-settings/replicated-deduplication-window#replicated_deduplication_window_seconds)
* [`non_replicated_deduplication_window`](/ar/reference/settings/merge-tree-settings/other#non_replicated_deduplication_window)

تخضع إزالة التكرار في الجداول التابعة للعروض المادية أيضًا لإعداد ملف تعريف المستخدم [`deduplicate_blocks_in_dependent_materialized_views`](/ar/reference/settings/session-settings/other#deduplicate_blocks_in_dependent_materialized_views)، وهو مُمكّن افتراضيًا منذ الإصدار 26.2. يجب أن يسمح كلا الإعدادين بذلك: يزيل `deduplicate_insert` تكرار البيانات المُدرجة في الجدول المصدر، ويزيل `deduplicate_blocks_in_dependent_materialized_views` أيضًا تكرار البيانات في الجداول التابعة. مكّن الإعدادين كليهما إذا كنت تريد إزالة التكرار الكاملة.

عند إدراج كتل في الجداول التابعة للعروض المادية، يحسب ClickHouse قيمة `block_id` عبر إجراء تجزئة لسلسلة تجمع بين قيم `block_id` من الجدول المصدر ومعرّفات إضافية. ويضمن ذلك إزالة تكرار دقيقة داخل العروض المادية، بحيث يمكن تمييز البيانات استنادًا إلى عملية إدراجها الأصلية، بغض النظر عن أي تحويلات طُبّقت عليها قبل وصولها إلى جدول الوجهة التابع للعرض المادي.

<div id="examples">
  ## أمثلة
</div>

<div id="identical-blocks-after-materialized-view-transformations">
  ### الكتل المتطابقة بعد التحويلات في العرض المادي
</div>

الكتل المتطابقة التي جرى إنشاؤها أثناء التحويل داخل العرض المادي لا تُزال تكراراتها، لأنها تستند إلى بيانات مُدرجة مختلفة.

إليك مثالًا:

```sql theme={null}
CREATE TABLE dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

CREATE MATERIALIZED VIEW mv_dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000
AS SELECT
    0 AS key,
    value AS value
FROM dst;
```

```sql theme={null}
SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;
```

تتيح لنا الإعدادات أعلاه إجراء استعلام على جدول يحتوي على سلسلة من الكتل، لا يحتوي كلٌّ منها إلا على صف واحد. هذه الكتل الصغيرة لا تُدمَج، وتبقى كما هي حتى تُدرَج في جدول.

نحدد إزالة التكرار في العرض المادي صراحةً، رغم أنها مفعّلة افتراضيًا:

```sql theme={null}
SET deduplicate_blocks_in_dependent_materialized_views=1;
```

```sql theme={null}
INSERT INTO dst SELECT
    number + 1 AS key,
    IF(key = 0, 'A', 'B') AS value
FROM numbers(2);

SELECT
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─key─┬─value─┬─_part─────┐
│   1 │ B     │ all_0_0_0 │
│   2 │ B     │ all_1_1_0 │
└─────┴───────┴───────────┘
```

نرى هنا أنه تم إدراج جزأين في الجدول `dst`. كتلتان من SELECT -- وجزآن عند الإدراج. تحتوي الأجزاء على بيانات مختلفة.

```sql theme={null}
SELECT
    *,
    _part
FROM mv_dst
ORDER BY all;
```

```response theme={null}
┌─key─┬─value─┬─_part─────┐
│   0 │ B     │ all_0_0_0 │
│   0 │ B     │ all_1_1_0 │
└─────┴───────┴───────────┘
```

هنا نرى أنه تم إدراج جزأين في جدول `mv_dst`. يحتوي هذان الجزآن على البيانات نفسها، لكن لم تُزل التكرارات بينهما.

```sql theme={null}
INSERT INTO dst SELECT
    number + 1 AS key,
    IF(key = 0, 'A', 'B') AS value
FROM numbers(2);

SELECT
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─key─┬─value─┬─_part─────┐
│   1 │ B     │ all_0_0_0 │
│   2 │ B     │ all_1_1_0 │
└─────┴───────┴───────────┘
```

```sql theme={null}
SELECT
    *,
    _part
FROM mv_dst
ORDER by all;
```

```response theme={null}
┌─key─┬─value─┬─_part─────┐
│   0 │ B     │ all_0_0_0 │
│   0 │ B     │ all_1_1_0 │
└─────┴───────┴───────────┘
```

نرى هنا أنه عند إعادة محاولة عمليات الإدراج، تُزال جميع البيانات المكررة. وتعمل آلية إزالة التكرار مع الجدولين `dst` و`mv_dst`.

<div id="identical-blocks-on-insertion">
  ### الكتل المتطابقة عند الإدراج
</div>

```sql theme={null}
CREATE TABLE dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;
```

الإدراج:

```sql theme={null}
INSERT INTO dst SELECT
    0 AS key,
    'A' AS value
FROM numbers(2);

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   0 │ A     │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘
```

باستخدام الإعدادات أعلاه، تنتج كتلتان من select– ونتيجةً لذلك، ينبغي أن تكون هناك كتلتان لإدخالهما في الجدول `dst`. ومع ذلك، نرى أنه لم تُدرج سوى كتلة واحدة في الجدول `dst`. حدث ذلك لأن الكتلة الثانية أُزيل تكرارها. فهي تحتوي على البيانات نفسها وعلى مفتاح إزالة التكرار `block_id`، الذي يُحتسب على شكل hash من البيانات المُدرجة. هذا السلوك ليس ما كان متوقعًا. مثل هذه الحالات نادرة الحدوث، لكنها ممكنة نظريًا. وللتعامل مع مثل هذه الحالات على نحو صحيح، يجب على المستخدم توفير `insert_deduplication_token`. لنُصلِح ذلك بالأمثلة التالية:

<div id="identical-blocks-in-insertion-with-insert_deduplication_token">
  ### الكتل المتطابقة عند الإدراج باستخدام `insert_deduplication_token`
</div>

```sql theme={null}
CREATE TABLE dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

SET max_block_size=1;
SET min_insert_block_size_rows=0;
SET min_insert_block_size_bytes=0;
```

الإدراج:

```sql theme={null}
INSERT INTO dst SELECT
    0 AS key,
    'A' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   0 │ A     │ all_2_2_0 │
│ from dst   │   0 │ A     │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘
```

أُدرجت كتلتان متطابقتان كما هو متوقع.

```sql theme={null}
SELECT 'second attempt';

INSERT INTO dst SELECT
    0 AS key,
    'A' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   0 │ A     │ all_2_2_0 │
│ from dst   │   0 │ A     │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘
```

تُزال التكرارات من عملية الإدراج المُعادَة كما هو متوقّع.

```sql theme={null}
SELECT 'third attempt';

INSERT INTO dst SELECT
    1 AS key,
    'b' AS value
FROM numbers(2)
SETTINGS insert_deduplication_token='some_user_token';

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   0 │ A     │ all_2_2_0 │
│ from dst   │   0 │ A     │ all_3_3_0 │
└────────────┴─────┴───────┴───────────┘
```

تُعامَل عملية الإدراج تلك أيضًا على أنها مكررة، رغم أنها تحتوي على بيانات مُدرجة مختلفة. لاحظ أن `insert_deduplication_token` له أولوية أعلى: لا يستخدم ClickHouse قيمة hash للبيانات عند توفير `insert_deduplication_token`.

<div id="different-insert-operations-generate-the-same-data-after-transformation-in-the-underlying-table-of-the-materialized-view">
  ### تُنتِج عمليات إدراج مختلفة البيانات نفسها بعد التحويل في الجدول الأساسي للعرض المادي
</div>

```sql theme={null}
CREATE TABLE dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

CREATE MATERIALIZED VIEW mv_dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000
AS SELECT
    0 AS key,
    value AS value
FROM dst;

SET deduplicate_blocks_in_dependent_materialized_views=1;

select 'first attempt';

INSERT INTO dst VALUES (1, 'A');

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER by all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   1 │ A     │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘
```

```sql theme={null}
SELECT
    'from mv_dst',
    *,
    _part
FROM mv_dst
ORDER by all;
```

```response theme={null}
┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst   │   0 │ A     │ all_0_0_0 │
└───────────────┴─────┴───────┴───────────┘
```

```sql theme={null}
select 'second attempt';

INSERT INTO dst VALUES (2, 'A');

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER by all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   1 │ A     │ all_0_0_0 │
│ from dst   │   2 │ A     │ all_1_1_0 │
└────────────┴─────┴───────┴───────────┘
```

```sql theme={null}
SELECT
    'from mv_dst',
    *,
    _part
FROM mv_dst
ORDER by all;
```

```response theme={null}
┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst   │   0 │ A     │ all_0_0_0 │
│ from mv_dst   │   0 │ A     │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘
```

نُدرِج بيانات مختلفة في كل مرة. ومع ذلك، تُدرَج البيانات نفسها في جدول `mv_dst`. لا تُزال التكرارات لأن بيانات المصدر كانت مختلفة.

<div id="different-materialized-view-inserts-into-one-underlying-table-with-equivalent-data">
  ### عمليات إدراج مختلفة من عروض مادية إلى جدول أساسي واحد ببيانات متكافئة
</div>

```sql theme={null}
CREATE TABLE dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

CREATE TABLE mv_dst
(
    `key` Int64,
    `value` String
)
ENGINE = MergeTree
ORDER BY tuple()
SETTINGS non_replicated_deduplication_window=1000;

CREATE MATERIALIZED VIEW mv_first
TO mv_dst
AS SELECT
    0 AS key,
    value AS value
FROM dst;

CREATE MATERIALIZED VIEW mv_second
TO mv_dst
AS SELECT
    0 AS key,
    value AS value
FROM dst;

SET deduplicate_blocks_in_dependent_materialized_views=1;

select 'first attempt';

INSERT INTO dst VALUES (1, 'A');

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER by all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   1 │ A     │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘
```

```sql theme={null}
SELECT
    'from mv_dst',
    *,
    _part
FROM mv_dst
ORDER by all;
```

```response theme={null}
┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst   │   0 │ A     │ all_0_0_0 │
│ from mv_dst   │   0 │ A     │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘
```

تم إدراج كتلتين متساويتين إلى الجدول `mv_dst` (كما هو متوقع).

```sql theme={null}
SELECT 'second attempt';

INSERT INTO dst VALUES (1, 'A');

SELECT
    'from dst',
    *,
    _part
FROM dst
ORDER BY all;
```

```response theme={null}
┌─'from dst'─┬─key─┬─value─┬─_part─────┐
│ from dst   │   1 │ A     │ all_0_0_0 │
└────────────┴─────┴───────┴───────────┘
```

```sql theme={null}
SELECT
    'from mv_dst',
    *,
    _part
FROM mv_dst
ORDER by all;
```

```response theme={null}
┌─'from mv_dst'─┬─key─┬─value─┬─_part─────┐
│ from mv_dst   │   0 │ A     │ all_0_0_0 │
│ from mv_dst   │   0 │ A     │ all_1_1_0 │
└───────────────┴─────┴───────┴───────────┘
```

تُزال تكرارات عملية إعادة المحاولة تلك في كلا الجدولين `dst` و`mv_dst`.
