Skip to main content

الحالة التجريبية

واجهة برمجة تطبيقات عميل البروتوكول الأصلي تجريبية. وقد تتغير واجهتها العامة في إصدار مستقبلي.
تُصدر واجهات العميل الرئيسي ومصدر البيانات وsession والعمليات، إلى جانب امتدادات حقن التبعيات، تحذير المصرّف CHTCP0001. للإقرار بهذا التحذير أثناء تقييم واجهة برمجة التطبيقات، أضفه إلى NoWarn في ملف مشروعك:
لا تُخفِ التحذير إلا بعد أن تتقبّل احتمال الحاجة إلى تعديل الشيفرة التي تستخدم واجهة برمجة التطبيقات في إصدار مستقبلي.

إصدارات .NET المدعومة

يدعم العميل الذي يعمل عبر البروتوكول الأصلي إصدارات .NET التالية:
  • .NET 8.0
  • .NET 9.0
  • .NET 10.0

إصدارات ClickHouse المدعومة

يدعم عميل TCP رسميًا أحدث إصدارين من إصدارات الدعم طويل الأمد (LTS)، وأحدث ثلاثة إصدارات من خادم ClickHouse.

التثبيت

يتوفر عميل البروتوكول الأصلي عبر TCP ضمن حزمة ClickHouse.Driver. ثبّت الحزمة من NuGet:
أو باستخدام مدير الحزم NuGet Package Manager:

البدء السريع

الترحيل من عميل HTTP

واجهة برمجة تطبيقات TCP مستقلة عن IClickHouseClient؛ فهي ليست خيارًا لوسيلة النقل في ClickHouseClient أو ClickHouseConnection. يمكن إعادة استخدام معظم شيفرات SQL، لكن عليك إنشاء ClickHouseTcpClient وترحيل كل عملية إلى نظيرتها عبر TCP.

الطرق المكافئة

على سبيل المثال، حلقة قارئ HTTP:
يصبح دفقًا غير متزامن لصفوف TCP:

الخيارات والمعلمات

لا يمكن استخدام QueryOptions وClickHouseParameterCollection الخاصّين بـ HTTP بالتبادل مع نظيريهما في TCP. انقل القيم إلى ClickHouseTcpQueryOptions، حيث تكون الإعدادات سلاسل نصية وتكون المعلمات جزءًا من كائن الخيارات نفسه:
يدعم عميل TCP العناصر النائبة الأصلية في ClickHouse بصيغة {name:Type}، لكنه لا يعيد كتابة العناصر النائبة بنمط ADO.NET مثل @name. كما أنه لا يتيح تحديد قاعدة بيانات أو دور أو رمز Bearer أو ترويسة مخصصة أو محلّل معلمات أو منسّق أو محوّل قراءة على مستوى كل استعلام. راجع القيود للاطلاع على الميزات التي لا تزال مقتصرة على HTTP.

دورة حياة الاتصال والنتيجة

كلا العميلين عاليَي المستوى آمن للاستخدام عبر خيوط تنفيذ متعددة، وينبغي إعادة استخدامهما. يحتفظ عميل TCP باتصالات أصلية دائمة بدلًا من اتصالات HTTP، وينفّذ IAsyncDisposable، وينبغي عادةً التخلّص منه بصورة غير متزامنة عند إيقاف تشغيل التطبيق. صفوف QueryAsync مملوكة للجهة المستدعية. أما كتل StreamAsync وأعمدتها فهي مُعارة، ولا تبقى صالحة إلا خلال التكرار الحالي؛ انسخ أي قيم تحتاج إليها بعد انتهائه. احرص دائمًا على إكمال التعداد أو التخلّص منه ليعود الاتصال إلى مجمّع الاتصالات. استخدم OpenSessionAsync عندما يلزم تنفيذ عدة عمليات على الاتصال نفسه مع الاحتفاظ بحالة session. راجع المثال الكامل للترحيل من HTTP إلى TCP للاطلاع على استخدام كلا العميلين مع الجدول نفسه.

التهيئة

يمكن تهيئة عميل يستخدم البروتوكول الأصلي عبر TCP بطريقتين:
  • سلسلة الاتصال: أزواج مفاتيح وقيم تفصل بينها فواصل منقوطة، تحدد نقطة نهاية الخادم، وبيانات اعتماد المصادقة، وخيارات الاتصال الأخرى.
  • كائن ClickHouseTcpClientOptions: كائن تهيئة محدد الأنواع وغير قابل للتغيير، يُعرَّف في الشيفرة.
مرّر أيًا منهما إلى مُنشئ ClickHouseTcpClient. استخدم ClickHouseTcpConnectionStringBuilder لتحليل سلسلة اتصال أو إنشائها وتحويلها إلى ClickHouseTcpClientOptions.
توضح الأقسام التالية الإعدادات المتاحة وقيمها الافتراضية وتأثير كل منها.

إعدادات الاتصال

تُحدَّد قيم خصائص TimeSpan في سلسلة الاتصال بالثواني.

صيغة البيانات والتسلسل

تجميع الاتصالات

ينفّذ الاتصال الواحد عملية واحدة في كل مرة. ويتيح مجمّع الاتصالات تشغيل العمليات بشكل متزامن، مع إعادة استخدام الاتصالات فيما بينها.

الأمان

من دون TLS، تنتقل كلمة المرور وجميع بيانات الاستعلام عبر الشبكة بلا تشفير. أبقِ TlsAllowInvalidCertificates مضبوطًا على false خارج بيئات التطوير المحلية.
للبروتوكول الأصلي الآمن نقطة نهاية منفصلة على الخادم، ولا يُفعَّل بترقية الاتصال القائم. يجب على عميل TLS الاتصال بمنفذ آمن للبروتوكول الأصلي؛ ولا يتحول تلقائيًا إلى اتصال بنص صريح. يُطبَّق ConfigureTls أخيرًا، ويمكنه تجاوز التحقق من صلاحية الشهادة واسم المضيف، لذا راجع دوال رد الاتصال المخصصة بعناية.

التسجيل وتصحيح الأخطاء

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

إعدادات مخصصة

تُطبّق ClickHouseTcpClientOptions.CustomSettings إعدادات خادم ClickHouse على كل استعلام وعملية إدراج. وتحلّ قيم ClickHouseTcpQueryOptions.Settings المحددة لكل عملية محلّ القيم المحددة على مستوى العميل إذا كانت تحمل الاسم نفسه.
في سلسلة الاتصال، أضف البادئة set_ إلى بداية كل إعداد من إعدادات الخادم:
لا تُضف البادئة set_ عند إضافة إعداد إلى CustomSettings أو إلى Settings الخاصة بكل عملية.

ClickHouseTcpQueryOptions

تحدّد ClickHouseTcpQueryOptions إعدادات خاصة بكل عملية. جميع الخصائص اختيارية.

ClickHouseTcpInsertOptions

يوسّع ClickHouseTcpInsertOptions الصنف ClickHouseTcpQueryOptions بإعدادات خاصة بعمليات الإدراج باستخدام كتل Native. كما تتوفر فيه جميع خصائص خيارات الاستعلام.

ClickHouseTcpClient

ClickHouseTcpClient هي واجهة برمجة التطبيقات عالية المستوى لبروتوكول TCP الأصلي. تنفّذ عبارات SQL واستعلامات تُرجع قيمة مفردة، وتُتيح النتائج على شكل كتل منظّمة حسب الأعمدة أو صفوف أو كائنات POCO، وتُدرج بيانات منظّمة حسب الأعمدة أو الصفوف، وتفتح sessions مرتبطة باتصال ثابت. يمكن استخدام هذا العميل بأمان من خيوط تنفيذ متعددة، وله مجمّع اتصالات خاص به. أنشئ عميلًا واحدًا لكل نقطة نهاية، وشاركه بين أجزاء التطبيق، وتخلّص منه عند إيقاف التشغيل. يمكن تنفيذ العمليات بالتزامن حتى الحدّ MaxPoolSize؛ أما العمليات الإضافية فتنتظر توفر اتصال لمدة لا تتجاوز PoolTimeout.

إنشاء عميل

أنشئ عميلًا من سلسلة اتصال أو من ClickHouseTcpClientOptions. راجع التهيئة لمعرفة الإعدادات المتاحة. باستخدام سلسلة اتصال:
باستخدام خيارات ذات أنواع محددة بوضوح:
يُفضَّل تحرير موارد العميل بطريقة غير متزامنة. يؤدي ذلك إلى إغلاق الاتصالات غير النشطة والانتظار مدةً تصل إلى PoolTimeout حتى تكتمل العمليات الجارية، ثم إيقاف ما لم يكتمل منها.

حقن التبعيات

تسجّل AddClickHouseTcpDataSource مصدر بيانات واحدًا يُعاد استخدام مثيله، وتوفّر عميله المشترك عبر IClickHouseTcpClient وIClickHouseTcpOperations:
يتولّى موفّر الخدمة إدارة مصدر البيانات ومجمّع الاتصالات. لا تحرّر موارد العميل المحقون؛ بل حرّر موارد الموفّر عند إيقاف تشغيل التطبيق. إذا لم تحدّد الخيارات LoggerFactory، يستخدم التسجيل ILoggerFactory الخاص بالحاوية. ويمكن تسجيل عدة مصادر بيانات مستقلة باستخدام serviceKey.

تنفيذ الاستعلامات

استخدم ExecuteAsync لتنفيذ العبارات التي لا تُرجع صفوفًا، مثل عبارات DDL وعمليات التعديل:
تكتمل الطريقة بعد أن يؤكد الخادم تنفيذ العبارة. وإذا أعادت العبارة صفوفًا، يقرأها ExecuteAsync ويتجاهلها. عند استخدام INSERT INTO ... VALUES، استخدم InsertAsync أو InsertRowsAsync وأنهِ عبارة SQL عند VALUES من دون إدراج قيم مباشرةً فيها.

قراءة البيانات

اختر واجهة برمجة تطبيقات القراءة المناسبة لشكل البيانات الذي يحتاجه التطبيق:

قراءة القيم المفردة

تُعيد ExecuteScalarAsync قيمة العمود الأول من الصف الأول على هيئة object:
تقرأ هذه الطريقة الاستجابة كاملةً وتتجاهل كل القيم التي تلي القيمة الأولى. لذا اكتب استعلامًا يُرجع صفًا واحدًا، ولا تعتمد عليها لإيقاف نتيجة كبيرة مبكرًا. وتكون النتيجة null سواء كانت القيمة الأولى NULL أو كان الاستعلام لا يُرجع أي صفوف.

قراءة الصفوف

تُمرّر QueryAsync الصفوف تباعًا، كلًّا منها في مصفوفة object[] مستقلة، وتُرتّب القيم فيها بحسب ترتيب أعمدة النتيجة:
تظل مصفوفة الصف صالحة بعد الانتقال إلى العنصر التالي في التعداد. ويُعدّ هذا المستوى مناسبًا عند عدم وجود نموذج للنتائج، لكنه يخصّص مصفوفة لكل صف ويغلّف أنواع القيم في كائنات.

قراءة البيانات باستخدام POCO

تُطابِق QueryAsync<T> الأعمدة مع الخصائص العامة التي يمكن تعيين قيم لها. وتُطابَق الأسماء بصرف النظر عن حالة الأحرف أو الشرطات السفلية؛ استخدم ClickHouseTcpColumn لتحديد اسم صريح، وClickHouseTcpNotMapped لاستبعاد خاصية.
يتضمّن تحويل الصفوف إلى كائنات POCO إجراء تحويلات وتخصيص كائن واحد لكل صف.

قراءة كتل البيانات المخزّنة بالأعمدة

تتيح StreamAsync الوصول إلى النتيجة بتنسيقها العمودي الأصلي كسلسلة من قيم Block. وهي أسرع طريقة لقراءة البيانات.
الكتل مستعارة. ولا تظل الكتلة وأعمدتها ومقاطع قيمها صالحة إلا خلال التكرار الحالي. لا تحرّرها أو تحتفظ بها؛ وأي بيانات يجب أن تبقى بعد انتهاء تنفيذ متن الحلقة، انسخها صراحةً إلى ذاكرة تملكها.
أكمل التعداد دائمًا أو حرّر المُعدِّد ليعود اتصاله إلى مجمّع الاتصالات.
تتيح Block.Column<T> الوصول إلى نوع CLR الذي تنتجه أداة فك الترميز. استخدم Block.ReadAs<T> أو واجهة متخصصة مثل IDateTimeColumn عند الحاجة إلى التحويل.

إدراج البيانات

ترسل عمليات الإدراج بالتنسيق الأصلي البيانات في كتل عمودية بصيغة ثنائية. يجب أن تكون عبارة SQL بصيغة INSERT INTO ... VALUES من دون قائمة قيم مضمّنة. استخدم أعمدة ذات أنواع محددة لتقليل المعالجة على جهة العميل، أو الصيغ التي تقبل الصفوف وكائنات POCO إذا كانت بيانات التطبيق منظّمة بالفعل حسب الصفوف.

الإدراج حسب الأعمدة

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

إدراج الصفوف

تقبل InsertRowsAsync صفوفًا من النوع object[]. وتقابل القيم الأعمدة في قائمة أعمدة SQL بحسب ترتيبها:
تُحوَّل الصفوف إلى أعمدة كتلةً تلو الأخرى. يجب أن يتضمن كل صف قيمةً واحدةً لكل عمود مذكور في العبارة، وأن تكون قيم العمود الواحد من نوع CLR واحد، إلا إذا كان النوع الهدف هو Variant أو Dynamic. لا تعدّل الصفوف قبل اكتمال العملية.

عمليات الإدراج باستخدام POCO

يطابق التحميل الزائد العام للدالة InsertRowsAsync<T> أعمدة الهدف مع الخصائص العامة التي يمكن قراءتها، وفق قواعد التسمية والسمات نفسها المستخدمة عند قراءة POCO:
يجب أن يقابل كل column مذكور في العبارة دالة جلب عامة متوافقة. تُحوَّل صفوف POCO كتلةً واحدةً من بيانات النقل في كل مرة، لذا قد تُكتشف قيمة غير صالحة في كتلة لاحقة بعد أن تكون الكتل السابقة قد أُرسلت بالفعل. يستبعد ClickHouseTcpNotMapped الخصائص التي يقتصر استخدامها على التطبيق، مثل ImportBatch، من عملية الربط.

معلمات SQL

يربط العميل الأصلي القيم بالعناصر النائبة {name:Type} الأصلية في ClickHouse. ولا يعيد كتابة العناصر النائبة @name المستخدمة وفق أسلوب ADO.NET.
تتطلب كل معلمة تحديد نوعها، إما في العنصر النائب المقابل لها في SQL أو في الخاصية ClickHouseTcpParameter.ClickHouseType. استخدم النوع Identifier لأسماء الجداول والأعمدة. إذا كانت قيمة DateTime أو DateTimeOffset تمثّل لحظة زمنية محددة، فأدرج منطقة زمنية مثل {timestamp:DateTime('UTC')}؛ وإلا فقد يتغيّر معنى القيمة بحسب المنطقة الزمنية لـsession الخادم.

معرّف الاستعلام

لكل عملية معرّف استعلام تستخدمه جداول النظام في ClickHouse وسجلات العميل ووحدات span للتتبّع. إذا كانت قيمة QueryId تساوي null أو كانت فارغة، ينشئ العميل معرّف GUID جديدًا. حدّد قيمته إذا كان لا بد من ربط العملية بمعرّف التطبيق:

تقدّم الاستعلام والبيانات الوصفية

اضبط ClickHouseTcpQueryOptions.Callbacks لتلقّي البيانات الوصفية أثناء تلقّي الاستجابة:
قيم التقدّم تمثّل زيادات، لا إجماليات تراكمية. تُنفَّذ دوال الاستدعاء الراجع تزامنيًا على خيط التنفيذ الذي يقرأ الاستجابة، وبترتيب الحزم؛ لذا اجعل تنفيذها سريعًا ولا تدعها ترفع استثناءات. الكتل المُمرَّرة إلى OnLog وOnProfileEvents وOnTotals وOnExtremes مستعارة، ويجب ألّا يُحتفظ بها خارج دالة الاستدعاء الراجع. لا يرسل ClickHouse حزم تقدّم الاستعلام للصفوف التي تُحمَّل أثناء الإدراج. استخدم OnBlockWritten لمراقبة الكتل التي يرسلها العميل؛ فهو يُبلّغ عن تقدّم النقل، لا عن تثبيت الخادم لعملية الإدراج.

الإلغاء

تقبل كل عملية CancellationToken:
يؤدي إلغاء نتيجة تُقرأ تدريجيًا أو التخلّي عنها إلى جعل اتصالها غير آمن لإعادة الاستخدام، لذا يُغلق العميل ذلك الاتصال بدلًا من إعادته إلى مجمّع الاتصالات. ويظل العميل قابلًا للاستخدام، فيفتح اتصالًا آخر أو يعيد استخدام اتصال موجود للعمليات اللاحقة. لذلك، قد يؤدي الإلغاء في session مثبّتة إلى إنهاء تلك الـsession وفقدان جداولها المؤقتة وإعداداتها.

معلومات الخادم وفحوصات حالته

تُعيد GetServerInfoAsync هوية الخادم وإصداره ومنطقته الزمنية ومعلومات البروتوكول التي جرى التفاوض عليها أثناء مصافحة الاتصال وفق البروتوكول الأصلي:
اربط إتاحة الميزات على مستوى نقل البيانات بـProtocolRevision، وهو رقم المراجعة الذي يتفق عليه العميل والخادم. واربط إتاحة ميزات SQL، مثل أنواع البيانات والدوال، بـVersion. تستخدم الطريقة اتصالًا قائمًا إذا توفر، وتفتح اتصالًا جديدًا إذا كان مجمّع الاتصالات فارغًا. استخدم PingAsync للتحقق من الجاهزية عبر البروتوكول الأصلي:
يؤكد نجاح اختبار الاتصال (ping) إمكانية الاتصال عبر البروتوكول الأصلي وصحة بيانات المصادقة. لكنه لا يؤكد إمكانية الوصول إلى جدول خاص بالتطبيق.

مزيد من الأمثلة

للاطلاع على أمثلة مكتملة وجاهزة للتشغيل تشمل قراءة البيانات، وإدراجها، وأنواع البيانات، والجلسات، وTLS، وإمكانية المراقبة، ومعالجة الأخطاء، راجع أمثلة البروتوكول الأصلي في مستودع GitHub.

sessions

تستعير عمليات العميل المعتادة أي اتصال متاح من مجمّع الاتصالات، لذا فإن الحالة الخاصة بالاتصال ليست معزولة، ولا يُضمن بقاؤها بين الاستدعاءات. وقد تتصل اتصالات مختلفة من المجمّع بخوادم مختلفة. افتح session إذا كان لا بد للجداول المؤقتة أو عبارات SET أو أي سلسلة أخرى من العمليات من استخدام اتصال واحد.
تتيح IClickHouseTcpSession واجهات برمجة التطبيقات نفسها التي يتيحها العميل للاستعلام والتنفيذ والإدراج واختبار الاتصال والحصول على معلومات الخادم. ولا تدعم الـsession الاستخدام المتزامن عبر خيوط تنفيذ متعددة. وتُنفَّذ عملياتها بالتتابع: يُرفض بدء عملية جديدة قبل انتهاء العملية الحالية. وتظل الـsession مشغولة بنتيجة تُقرأ تدريجيًا حتى يكتمل تعداد عناصر النتيجة أو يُتخلّص من كائن المُعدِّد الخاص بها. تشغل كل session خانة واحدة من MaxPoolSize طوال فترة وجودها. ويمكن للعميل مواصلة استخدام اتصالات أخرى من مجمّع الاتصالات، لكن إذا لم يضمّ المجمّع سوى اتصال واحد، تنتظر عمليات العميل الأخرى حتى يُتخلّص من الـsession أو تنقضي المهلة المحددة في PoolTimeout. تخلّص من الـsession قبل التخلّص من العميل التابع له. ويؤدي التخلّص منها إلى إغلاق الاتصال المخصّص لها بدلًا من إعادته إلى المجمّع، ما يمنع الجهات التي تستخدمه لاحقًا من وراثة جداولها المؤقتة أو إعداداتها. وقد تصبح الـsession غير قابلة للاستخدام بسبب فشل الاتصال أو البروتوكول، أو الإلغاء، أو عدم اكتمال دفق النتائج؛ وعندما تصبح قيمة IsOpen هي false، افتح session جديدة.

أفضل الممارسات

عمر العميل وتجميع الاتصالات

أنشئ مثيلًا واحدًا من ClickHouseTcpClient أو ClickHouseTcpDataSource لكل نقطة نهاية وتهيئة مميزتين، وأعد استخدامه طوال عمر التطبيق. يمكن استخدام العميل بأمان عبر خيوط تنفيذ متعددة، وهو يدير مجمّع اتصالاته؛ أما إنشاء عميل لكل عملية فينشئ مجمّعًا جديدًا في كل مرة ويحول دون إعادة استخدام الاتصالات. في التطبيقات التي تستخدم حقن التبعيات، سجّل AddClickHouseTcpDataSource مرة واحدة واحقن IClickHouseTcpClient. يتولى موفّر الخدمات إدارة عمر العميل، لذا يجب ألا تتخلص المكوّنات التي تستخدمه من المثيل المحقون. أما خارج نطاق حقن التبعيات، فتخلّص من العميل عند إيقاف التطبيق باستخدام await using. يعالج كل اتصال عبر البروتوكول الأصلي عملية واحدة في كل مرة. لذلك، يحدّ MaxPoolSize من عدد الاتصالات المفتوحة والعمليات المتزامنة معًا؛ وينتظر المستدعون الآخرون توفّر خانة شاغرة لمدة تصل إلى PoolTimeout. اختر قيمة تستوعب التزامن الفعلي في التطبيق دون تجاوز حدود الاتصالات والاستعلامات على جانب الخادم. زيادة هذه القيمة لا تسرّع الاستعلام الواحد. ضع في اعتبارك كيفية استخدام المكوّنات التالية لمجمّع الاتصالات:
  • تحتفظ النتيجة التي تُقرأ تدريجيًا باتصالها حتى يُتخلَّص من معدِّدها.
  • تحتفظ session باتصال واحد طوال عمرها، ولا تقبل إلا عملية واحدة في كل مرة.
  • يؤدي ترك نتيجة دون إكمال قراءتها، أو إلغاء عملية قيد التنفيذ، أو حدوث فشل في البروتوكول أو الاتصال، إلى إغلاق الاتصال بدلًا من إعادة استخدامه.
تخلّص من sessions فور انتهاء استخدامها، واحرص دائمًا على تعداد النتائج غير المتزامنة حتى النهاية أو التخلّص من معدِّدها. استخدم فئة التسجيل ClickHouse.Driver.Tcp.Pool لتشخيص استنفاد مجمّع الاتصالات، أو إغلاق الاتصالات على نحو غير متوقع، أو تكرار إنشاء اتصالات جديدة.

المهلات الزمنية والإلغاء

يحدد عميل TCP مهلة مستقلة لكل نوع من الانتظار: قد تستغرق عملية الحصول على اتصال من المجمّع، إذا انتظرت توفر خانة أولًا ثم أنشأت اتصالًا، ما يصل إلى PoolTimeout + DialTimeout. تُحتسب مهلة ReadTimeout من جديد مع كل قراءة عبر طبقة النقل، لذا قد يستمر استعلام طويل يتواصل خلاله إرسال معلومات التقدم أو البيانات مدةً تتجاوز هذه القيمة. اضبطها على قيمة تكفي لتغطية فترات صمت الخادم المتوقعة؛ ولا تضبطها على TimeSpan.Zero إلا إذا كانت مهلة أخرى تقيّد مدة العملية على نحو موثوق. استخدم رمز إلغاء عندما تحتاج إلى مهلة تشمل العملية من بدايتها إلى نهايتها:
يحاول العميل إرسال حزمة Cancel عبر البروتوكول الأصلي عندما يكون ذلك آمنًا، ثم يغلق اتصالًا لم تُصرَّف استجابته بالكامل. وتظل العمليات اللاحقة على العميل المرتبط بمجمّع الاتصالات ممكنة، لكن الإلغاء قد يجعل session المثبّتة غير قابلة للاستخدام. وقد لا تُعرف نتيجة عملية إدراج أُلغيت أو انتهت مهلتها؛ لذا اتبع إرشادات إعادة محاولة الإدراج بدلًا من إعادة تنفيذها دون التحقق من نتيجتها.

التعامل مع التاريخ والوقت

يُفضّل استخدام DateTime('UTC') أو DateTime64(S, 'UTC') للطوابع الزمنية، واستخدام DateTimeOffset أو DateTime بقيمة Kind تساوي Utc في شيفرة التطبيق. فهذا يحدّد اللحظة الزمنية المقصودة بوضوح ويجنّب الاعتماد على المنطقة الزمنية للخادم أو الـsession. يطبّق عميل TCP القواعد التالية عند كتابة قيم DateTime: يُرفَض الوقت غير المحدّد الذي يُتخطّى عند الانتقال إلى التوقيت الصيفي لأنه لا يقابل أي لحظة زمنية. أما الوقت الملتبس عند العودة إلى التوقيت السابق، فيُختار ظهوره الأول. استخدم DateTimeOffset عندما يجب تحديد الاختيار صراحةً. عند استخدام معلمات SQL لتمثيل لحظة زمنية، أدرج المنطقة الزمنية في العنصر النائب:
عند قراءة البيانات المخزّنة بالأعمدة، يُظهر DateTime وDateTime64 أعدادهما الخام من نوع uint أو long افتراضيًا. استخدم Block.ReadAs<DateTimeOffset> أو IDateTimeColumn.GetDateTimeOffset أو خاصية POCO مطابقة إذا كان التعامل مع قيمة تقويمية أنسب. واحتفظ بالعدد الخام عندما تكون كل خانة مهمة: تبلغ أصغر وحدة زمنية في DateTimeOffset مقدار 100 نانوثانية، لذا فإن قراءة DateTime64 بمقياس 8 أو 9 من خلاله تؤدي إلى فقدان الدقة دون تلك الوحدة. استخدم DateOnly مع Date وDate32. واستخدم TimeSpan مع قيم Time وTime64 التي قد تكون سالبة أو تتجاوز 24 ساعة؛ ولا يكون TimeOnly مناسبًا إلا إذا كانت قيم العمود تقتصر على وقت من اليوم.

البث وعمر النتائج

استخدم StreamAsync والأعمدة محددة الأنواع لمعالجة البيانات بمعدل نقل مرتفع. يتماشى ذلك مع تنظيم البيانات حسب الأعمدة في ClickHouse، ويجنّب إنشاء مصفوفات لكل صف وتغليف القيم وتخصيص كائنات POCO. استخدم QueryAsync<T> عندما تكون الحاجة إلى نموذج يمتلكه التطبيق أهم من تقليل عمليات تخصيص الذاكرة إلى أدنى حد، واستخدم الإصدار غير محدد النوع QueryAsync فقط عندما لا يكون المخطط معروفًا وقت التصريف. الكتل التي يعيدها StreamAsync مستعارة. لا تبقى الكتلة وأعمدتها وأعمدتها الفرعية المركّبة وجميع وحدات span صالحة إلا أثناء التكرار الحالي للحلقة. عالجها في موضعها أو انسخ القيم التي يجب الاحتفاظ بها بعد انتهاء التكرار:
لا تتولَّ تحرير كتلة أعادها المُعدِّد بنفسك. اترك لـawait foreach مهمة تحرير المُعدِّد. إذا كنت تحتاج إلى جزء فقط من النتيجة، فحدّد ذلك في SQL باستخدام LIMIT، واختر الأعمدة المطلوبة فقط. يؤدي التوقف مبكرًا إلى إلغاء بقية الاستجابة، ويمنع إعادة استخدام ذلك الاتصال.

بنية عملية الإدراج وتجميع الدُفعات

فضّل استخدام InsertAsync مع الأعمدة محددة الأنواع إذا كانت البيانات منظّمة في أعمدة أصلًا، فهو يتطلب أقل قدر من التحويل من جهة العميل. ويُعدّ InsertRowsAsync<T> الخيار الأنسب لبيانات POCO؛ أما صفوف object[] غير محددة الأنواع فهي الأكثر مرونة، لكنها تنشئ مصفوفات وتغلّف أنواع القيم. أرسل عددًا كافيًا من الصفوف في كل استدعاء إدراج بدلًا من تنفيذ عمليات إدراج صغيرة كثيرة. وضمن الاستدعاء الواحد، يقسّم MaxRowsPerBlock البيانات إلى كتل بصيغة النقل الأصلية. كما تضع قيمته الافتراضية، البالغة 50,000 صف، حدًا لحجم مخازن الأعمدة المؤقتة المستخدمة عند تحويل مدخلات الصفوف وPOCO. وقد تؤدي زيادة هذه القيمة إلى تحسين معدل النقل للصفوف قليلة الأعمدة، لكنها ترفع ذروة استهلاك الذاكرة؛ أما ضبطها على null فيؤدي إلى كتابة عملية الإدراج كاملةً في كتلة واحدة وتحويل جميع المدخلات المنظّمة في صفوف لتلك الكتلة معًا. يحدّ MaxSendBufferBytes، على نحو مستقل، من كمية البيانات المُرمَّزة المخزّنة مؤقتًا قبل تفريغها إلى المقبس. وهو حدّ مرن يُفحَص بين الأعمدة، لذا يمكن أن يتجاوزه عمود عريض واحد. تُحوَّل مدخلات الصفوف وPOCO كتلةً تلو الأخرى. لذا قد لا تُكتشف قيمة غير صالحة في كتلة لاحقة إلا بعد إرسال الكتل السابقة. تحقّق من السماح بالقيم الفارغة ومن أنواع CLR قبل الإدراج إذا لم تكن جودة البيانات مضمونة، واضبط DeduplicationToken على قيمة مشتقة من البيانات كلما كان من الممكن إعادة محاولة إدراج الدفعة المنطقية.

أنواع البيانات المدعومة

توضّح الجداول أدناه الفرق بين النوع الذي يعيده IColumn<T> مفكك الترميز والأنواع الإضافية المتاحة بالتحويل عبر Block.ReadAs<T>، أو بربط كائنات POCO عبر QueryAsync<T>، أو بعمليات الإدراج. ويمكنك الاستعلام من محلّل الربط نفسه الذي تستخدمه هذه العمليات عمّا إذا كان ربط معيّن مدعومًا:
تُطبَّق قواعد الربط الخاصة بـNullable وArray وTuple وMap وLowCardinality تعاوديًا على الأنواع الداخلية لكلٍّ منها.

مطابقة الأنواع: القراءة من ClickHouse

يشير Default .NET type إلى النوع T الذي تتيحه Block.Column<T> وIColumn<T>. ويمكن قراءة الأنواع المدرجة في العمود Also readable as باستخدام Block.ReadAs<T> وخصائص POCO.

أنواع الأعداد الصحيحة

أنواع الأعداد ذات الفاصلة العائمة

الأنواع العشرية

يخزّن ClickHouseTcpDecimal الجزء الدالّ بوصفه عددًا صحيحًا بأي حجم، إلى جانب مقياسه، مما يتيح الاحتفاظ بالقيم التي تتجاوز دقتها النطاق الذي يدعمه decimal.

النوع المنطقي

أنواع String

استخدم IStringColumn.GetBytes(row) أو اقرأ البيانات بالنوع byte[] إذا كانت قد لا تكون بترميز UTF-8 صالح. يحتفظ FixedString(N) بجميع البايتات الـN، بما فيها البايتات الصفرية في نهايتها.

أنواع التاريخ والوقت

التمثيل الافتراضي هو العدد الصحيح الخام، حتى تحتفظ القراءة العمودية بالقيمة كما تُنقل تمامًا. وتستخدم التحويلات إلى قيم التاريخ والوقت المنطقة الزمنية المحددة في النوع، أو المنطقة الزمنية للجلسة إذا لم يحدد النوع منطقة زمنية. ترفع قراءة Time أو Time64 بوصفه TimeOnly استثناءً إذا كانت القيمة سالبة أو بلغت 24 ساعة فأكثر؛ استخدم TimeSpan لتمثيل نطاق قيم ClickHouse كاملًا.

أنواع التعداد

تُتيح IEnumColumn أيضًا الاطلاع على الربط المُعلَن بين تسميات التعداد وقيمها الرقمية.

أنواع قياسية أخرى

الأنواع المركبة

يمكن أن تضمّ المجموعات المرتبة ما يصل إلى سبعة عناصر. لا يتقيّد عمود Nested بعدد محدد من العناصر، ويُفضّل قراءته عبر INestedColumn، الذي يتيح الوصول إلى أعمدة الحقول المسطّحة المسماة وإزاحات الصفوف المشتركة دون تخصيص سجلات مغلّفة. ومع الإعداد الافتراضي flatten_nested = 1 في ClickHouse، تصل الحقول المتداخلة بدلًا من ذلك في أعمدة Array(T) منفصلة، تتضمن أسماؤها نقاطًا.

أنواع Variant وDynamic وJSON

تُرجع Variant وDynamic قيمة CLR للنوع المختار في كل صف، أو null. وتُتيح عروضهما العمودية الوصول إلى دفق المميّز وعمود فرعي محدد النوع لكل نوع أثناء التنفيذ، مما يغني عن تغليف القيم عند معالجة البيانات عموديًا. يقرأ عميل TCP بيانات JSON عبر آلية تسلسل String في ClickHouse. ويُفعّل العميل الإعداد output_format_native_write_json_as_string = 1 افتراضيًا؛ وتعطيله يجعل قراءة JSON غير مدعومة. يحلّل ClickHouse بيانات JSON ويوحّد صيغتها، لذا قد يختلف النص الناتج عن النص المُدرج في ترتيب المفاتيح والمسافات البيضاء وصيغة الأرقام.

الأنواع الهندسية

يُقدَّم Geometry في صورة IVariantColumn يشمل الأنواع الهندسية الستة.

نوع QBit

يدعم عميل TCP صيغة QBit(T, N) ذات الوسيطين، من دون stride. أما تخطيط التخزين ذو الوسائط الثلاثة الذي يستخدم stride فغير مدعوم.

أنواع AggregateFunction

يحتوي العمود من نوع AggregateFunction على حالة وسيطة خاصة بالدالة. استخرج قيمتها النهائية على الخادم، مثلًا باستخدام sumMerge(column)، ثم اقرأ القيمة الناتجة بدلًا من الحالة الوسيطة.

مطابقة الأنواع: الكتابة إلى ClickHouse

يمثّل كل إدخال نوع CLR لصف واحد ضمن IColumn المُمرَّر إلى InsertAsync. وهذه المطابقات دقيقة تمامًا: لا يُجري عميل TCP تحويلات ضمنية على غرار Convert.

أنواع الأعداد الصحيحة

أنواع الأعداد ذات الفاصلة العائمة

عند كتابة BFloat16، تُقتطع كل قيمة float لتلائم تمثيل Brain Floating Point ذي 16 بت.

الأنواع العشرية

ترفع عملية الكتابة استثناء OverflowException إذا تجاوز الجزء الدالّ من العدد، بعد تطبيق المقياس، الدقة المعلنة.

النوع المنطقي

أنواع String

لا يقبل FixedString(N) النوع string عمدًا؛ لذا رمِّز القيمة وأكملها بحشو مناسب صراحةً حتى يكون تمثيلها الثنائي المحدد واضحًا بلا لبس.

أنواع التاريخ والوقت

تُفسَّر الأعداد الصحيحة الأولية وفق الوحدات الموضحة في جدول القراءة. يحافظ DateTimeOffset على اللحظة الزمنية نفسها. ويُفسَّر DateTime بحسب قيمة Kind الخاصة به؛ فإذا كانت القيمة Unspecified، فتُفسَّر على أنها الوقت المحلي بحسب المنطقة الزمنية للعمود، أو بحسب المنطقة الزمنية للجلسة إذا لم يحدد العمود منطقة زمنية.

أنواع التعداد

تُرفض التسميات غير المعروفة قبل إرسال البيانات.

أنواع البيانات القياسية الأخرى

الأنواع المركبة

البنية المقبولة تعاودية، لذا يقبل Array(Nullable(DateTime)) قيمة من النوع DateTime?[] لكل صف، ويقبل Map(String, UInt32) قيمة من النوع KeyValuePair<string, uint>[]. تستخدم الكتابة المباشرة إلى Nested بنية الأعمدة الكثيفة الناتجة عن قراءة سابقة. أما عند إنشاء عمليات الإدراج في التطبيق، فاحتفظ بالتمثيل الافتراضي flatten_nested = 1، واكتب كل حقل Array(T) يتضمن اسمه نقطةً كعمود مستقل.

أنواع Variant وDynamic وJSON

في Variant، يجب أن يطابق نوع القيمة وقت التشغيل نوع CLR الافتراضي لأحد الأنواع البديلة دون لبس. ولا تُستخدم داخل النوع البديل تعيينات تسهيلية، مثل كتابة قيمة DateTime إلى بديل من نوع DateTime؛ بل استخدم النوع الخام الافتراضي لذلك البديل. يدعم Dynamic القيم المفردة وقيم المصفوفات والخرائط والصفوف التي تدعمها البنية تعاوديًا.

الأنواع الهندسية

في عمود Geometry يُنشئه التطبيق، لا يكون شكل CLR مميزًا إلا لـPoint وMultiPolygon. فكلٌّ من Ring وLineString له الشكل نفسه، وكذلك Polygon وMultiLineString، لذا لا يستطيع العميل استنتاج النوع الذي تمثّله قيمة object. أما عمود Geometry بعد فك ترميزه، فيحتفظ بمميّزات أنواعه ويمكن إعادة إدراجه دون هذا الالتباس.

نوع QBit

أنواع AggregateFunction

الضغط

يُفعّل العميل الضغط افتراضيًا ويستخدم LZ4 لضغط الكتل التي يكتبها؛ ويستخدم ClickHouse أيضًا LZ4 افتراضيًا لكتل الاستجابة. يُطبَّق الضغط على كتل النتائج والكتل التي تُحمَّل أثناء عمليات الإدراج، بينما يحتفظ نص الاستعلام ومعلومات التقدّم والاستثناءات وحزم البروتوكول الأخرى بترميزها المعتاد أثناء النقل. استخدم مفتاح Compression في سلسلة الاتصال لاختيار المرمِّز الذي يستخدمه العميل:
تستخدم التهيئة المكافئة ذات الأنواع المحددة صراحةً IClickHouseCompressor:
اضبط Compressor = null لتعطيل الضغط. يجب أن يدعم الضاغط المخصّص تأطير الكتل الأصلي؛ وتُرفض الضواغط التي لا تدعم سوى متون HTTP عند إنشاء العميل.

اختيار مرمِّز الاستجابة

يحدّد Compressor كيفية ضغط الكتل التي يكتبها العميل. تطلب حزمة الاستعلام بالتنسيق الأصلي من الخادم ضغط الاستجابة، لكنها لا تحدّد مرمِّزًا بعينه؛ لذلك يختار ClickHouse مرمِّز الاستجابة وفقًا لإعداد network_compression_method. ‏LZ4 هو المرمِّز الافتراضي للخادم. حدّد مرمِّز الاستجابة لكل عملية عند الحاجة:
يستهلك LZ4 عمومًا قدرًا أقل من موارد CPU، وهو الخيار الافتراضي الأنسب للشبكات السريعة. وينتج ZSTD عمومًا إطارات أصغر مقابل استهلاك أعلى قليلًا لموارد CPU. وقد يفيد تعطيل الضغط إذا كان الخادم على المضيف نفسه أو متصلًا عبر وصلة أخرى فائقة السرعة. قِس الأداء باستخدام بيانات ممثلة قبل تغيير الإعداد الافتراضي.

معالجة الأخطاء

تُمثَّل حالات الفشل التي يُبلغ عنها ClickHouse أو الاتصال الأصلي باستثناءات ترث من ClickHouseTcpException، الذي يرث بدوره من DbException: يوفّر ClickHouseTcpServerException الخاصيتين RawCode، التي تحتوي على الرمز الرقمي كما أرسله الخادم، وCode، التي تحتوي على قيمة ClickHouseErrorCode المقابلة إذا كان المشغّل يعرّفها. ويتضمّن أيضًا اسم استثناء الخادم في Name، وتتبع مكدسه في ServerStackTrace، وأي استثناءات متداخلة من الخادم عبر InnerException.
الرموز غير الممثَّلة في ClickHouseErrorCode تحمل القيمة Code == ClickHouseErrorCode.Unknown؛ لذا افحص RawCode ولا تفترض أن التعداد يشمل جميع رموز error في ClickHouse. تحتفظ أخطاء التحقق من الوسائط وأخطاء دورة حياة الكائنات بأنواع الاستثناءات المعتادة في ‎.NET. يؤدي الإلغاء إلى إطلاق OperationCanceledException. ويؤدي DialTimeout وReadTimeout إلى إطلاق ClickHouseTcpConnectionException يتضمن استثناءً داخليًا من نوع TimeoutException، ويُستبعَد الاتصال. أما PoolTimeout فيؤدي إلى إطلاق TimeoutException عادي، وليس ClickHouseTcpException: إذ لم يفشل أي اتصال، والحل هو تقليل العمليات المتزامنة، أو زيادة حجم مجمّع الاتصالات، أو إكمال تعداد النتائج.

إعادة محاولة العمليات

إذا فشل الاتصال أو انتهت المهلة أثناء إدراج الصفوف، فلن يُعرف ما إذا نجحت العملية: إذ ربما ثبّت الخادم الصفوف قبل أن يفقد العميل الاستجابة. عيّن قيمة ثابتة لـDeduplicationToken للدفعة المنطقية قبل إعادة محاولتها:
استخدم الرمز نفسه عند تكرار محاولة إرسال تلك الدفعة، ورمزًا مختلفًا للبيانات الجديدة. أما العمليات الأخرى، فلا تُعِد المحاولة إلا إذا كان تكرار العبارة آمنًا وكان الإخفاق المعني عارضًا؛ إذ تتطلب معظم أخطاء الخادم تعديل الاستعلام أو التهيئة بدلًا من إعادة المحاولة.

التسجيل والتشخيص

يتكامل عميل TCP مع Microsoft.Extensions.Logging. التسجيل اختياري؛ وعند عدم توفّر LoggerFactory، لا ينشئ العميل أي مسجّلات ولا ينسّق أي رسائل سجل.
عند تسجيل العميل باستخدام ملحقات حقن التبعيات، يستخدم ILoggerFactory الخاص بالحاوية ما لم تكن الخيارات المقدَّمة قد حدّدت واحدًا بالفعل.

فئات التسجيل

هيّئ الفئات باستخدام تهيئة التسجيل القياسية في .NET:
تُسجَّل رسالة بدء العملية بمستوى Debug، وتتضمن من نص SQL ما لا يزيد على StatementMaxLength محرفًا. القيمة الافتراضية هي خمسة محارف. اضبط القيمة على صفر أو أقل لاستبعاد نص العبارة من السجلات، ولا ترفعها إلا بعد مراعاة أن المعلمات والقيم الحرفية قد تحتوي على بيانات حساسة.

رسائل سجل الخادم

يرصد تكامل تسجيل الأحداث سلوك جهة العميل. أما حزم سجل الاستعلامات الخاصة بـ ClickHouse، فهي منفصلة وتُرسَل إلى ClickHouseTcpQueryCallbacks.OnLog. فعِّل إرسالها باستخدام إعداد الخادم send_logs_level:
تُستعار كتلة السجل وتُحرَّر عند انتهاء دالة الاستدعاء. عالجها بالتزامن أو انسخ منها القيم التي يلزم الاحتفاظ بها. احرص على سرعة تنفيذ دوال الاستدعاء وألّا ترفع استثناءات؛ فأي استثناء ترفعه دالة الاستدعاء يُنهي العملية واتصالها.

OpenTelemetry

يُصدر عميل TCP وحدات span للتتبّع الموزّع عبر واجهة برمجة التطبيقات System.Diagnostics.Activity في ‎.NET. اشترك في مصدر نشاط TCP باستخدام موفّر تتبّع OpenTelemetry:
لتطبيق يعمل على وحدة التحكم أو للإعداد اليدوي:
اسم مصدر النشاط هو ClickHouse.Driver.Tcp، وهو منفصل عن مصدر عميل HTTP، لذا يمكن جمع بيانات أيٍّ من وسيلتَي النقل على حدة. وإذا لم يشترك أي مستمع، فلن تُنشئ العمليات أي أنشطة.

وحدات span والسمات

يُصدر العميل وحدات span لعمليات SQL وطلبات التحقق من الاتصال والاتصالات الجديدة. وتُسمّى وحدة span الخاصة بعبارة SQL باسم أول كلمة مفتاحية فيها، مثل SELECT أو INSERT؛ أما العبارات التي لا يمكن التعرّف على كلمتها المفتاحية الأولى، فتُسمّى وحدات span الخاصة بها query. وتغطي وحدة span المسماة connect إنشاء اتصال المقبس والتفاوض على TLS والمصافحة وفق البروتوكول الأصلي. وتشمل وحدات span الخاصة بالعبارات أيضًا الوقت المستغرق في انتظار اتصال متاح من مجمع الاتصالات. لا تظهر العدادات إلا إذا كانت لدى الخادم أو العميل قيمة ذات معنى للإبلاغ عنها. فعلى سبيل المثال، تُبلّغ عملية الإدراج التي تُحمّل كتل بيانات عن الصفوف التي أرسلها العميل، لكنها لا تتلقى من الخادم أي عدادات للقراءة. وتتضمن وحدات span الفاشلة أيضًا حدث exception يضم نوع الاستثناء ورسالته وتتبّع المكدس.

نص SQL والبيانات الحساسة

يُستبعَد نص SQL من spans افتراضيًا. ولتضمينه، فعِّله صراحةً واضبط حدًا مناسبًا:
يحدّ StatementMaxLength طول نص SQL في كلٍّ من السمة db.query.text وسجلات تصحيح الأخطاء. وإذا كانت قيمته صفرًا أو أقل، يُحذف نص SQL من كليهما. راجع أيضًا رسائل الاستثناء المُصدَّرة وتتبّعات المكدس، إذ قد تتضمن أخطاء الخادم تفاصيل الاستعلام.

تمرير سياق التتبع

عندما يستخدم Activity.Current صيغة معرّف W3C، يضمّن العميل معرّف التتبع ومعرّف span وعلامات التتبع وحالة التتبع في حزمة الاستعلام الأصلية. ويمكن لـ ClickHouse بعد ذلك إنشاء وحدات span للخادم ضمن التتبع الموزّع نفسه. ويظل جمع وحدات span على جانب الخادم وأخذ العينات منها محكومَين بتهيئة ClickHouse؛ فعلى سبيل المثال، يمكن ضبط احتمال أخذ العينات لكل استعلام:
يمكن استخدام معرّف الاستعلام المُمرَّر مع معرّف التتبّع لربط span العميل بجدول system.query_log، وكذلك بجدول system.opentelemetry_span_log في ClickHouse عند تهيئته.

القيود

لا يزال عميل TCP تجريبيًا، ولا يوفّر جميع الميزات المتاحة في عميل HTTP.

الميزات المتاحة عبر HTTP فقط

واجهة برمجة تطبيقات TCP ليست موفّر ADO.NET، ولا يمكن استخدامها مع أدوات ربط الكائنات بقواعد البيانات (ORMs). وهي لا تدعم أيضًا الإدخال والإخراج بصيغ CSV أو JSONEachRow أو Parquet أو عبر تدفّق بيانات خام؛ أو المصادقة باستخدام رمز حامل أو ترويسات HTTP مخصّصة؛ أو تخصيص تحديد أنواع المعلمات أو تنسيقها أو تحويلها عند القراءة؛ أو تعيين قاعدة بيانات أو دور لكل استعلام. استخدم عميل HTTP إذا كان التطبيق يحتاج إلى أيٍّ من هذه الميزات.

معلمات SQL

لا تُدعَم سوى العناصر النائبة {name:Type} الأصلية في ClickHouse؛ ولا يعيد عميل TCP كتابة العناصر النائبة @name وفق صيغة ADO.NET. في إصدارات ClickHouse من 25.8 إلى 26.6، قد تُعامَل أسماء المعلمات التي تطابق إعدادات الخادم، مثل limit أو offset، على أنها إعدادات، ومن ثم تُرفَض. أعد تسمية هذه المعلمات، مثلًا إلى row_limit، إذا كنت تدعم تلك الإصدارات.

تغطية أنواع البيانات

يوضّح قسم أنواع البيانات المدعومة جميع حالات المطابقة. وللمرمِّز الأصلي الحالي القيود المهمة التالية:
  • يمكن أن تضمّ أنواع Tuple سبعة عناصر على الأكثر.
  • الحالات الوسيطة لـAggregateFunction(function, ...) غير مدعومة. احسب قيمها النهائية على الخادم، مثلًا باستخدام sumMerge(column)، واقرأ النتيجة بدلًا منها.
  • لا يُدعم سوى تخطيط QBit(T, N) ذي الوسيطين، من دون تقسيم الأبعاد إلى مجموعات ثابتة الحجم.
  • يستخدم JSON تسلسل String الخاص بـClickHouse، ويتطلب output_format_native_write_json_as_string = 1، وهي قيمة يطلبها العميل افتراضيًا.
  • لا تتوفّر لعمليات الإدراج التي ينشئها التطبيق بنية موجّهة للصفوف لـNested(...) عندما تكون flatten_nested = 0. استخدم بدلًا منها أعمدة Array(T) المسطّحة ذات الأسماء المنقّطة، وهي الخيار الافتراضي.
  • لا يمكن لعمود Geometry ينشئه التطبيق التمييز تلقائيًا بين بدائل تشترك في بنية CLR نفسها، مثل Ring وLineString. أدرج النوع الهندسي المحدّد، أو أعِد إدراج عمود Geometry مفكك الترميز الذي يحتفظ بمميّزاته.

إعادة المحاولة تلقائيًا

لا يعيد العميل محاولة تنفيذ العمليات الفاشلة تلقائيًا. أعد محاولة تنفيذ العمليات التي يمكن تكرارها بأمان فقط، وحدّد قيمة ثابتة لـDeduplicationToken قبل إعادة محاولة عملية إدراج لم تُعرف نتيجتها. راجع إعادة محاولة تنفيذ العمليات لمزيد من التفاصيل.
آخر تعديل في ١٤ أكتوبر ٢٠٢٦