نوع العمود JSON جاهز للاستخدام في بيئات الإنتاج بدءًا من ClickHouse 25.3+. ولا يُنصح باستخدام الإصدارات الأقدم في بيئات الإنتاج.
قرار سريع
- إذا كان لكل حقل نوع معروف ومستقر، وكان المخطط نادر التغيّر → أعمدة محددة النوع
- إذا كانت معظم الحقول مستقرة، لكن بعض الأجزاء ديناميكيًا أو غير متوقع → هجين (أعمدة محددة النوع + JSON)
- إذا كانت البنية بأكملها ديناميكية، مع مفاتيح تظهر وتختفي بين السجلات → عمود JSON أصلي
- إذا كانت الحقول الديناميكية أزواج مفتاح-قيمة ذات نوع قيمة متسق (مثل tags النصية وmetrics الرقمية)
→
Mapبدلًا من JSON - إذا كنت تخزّن وتسترجع blob JSON فقط من دون استعلامات على مستوى الحقل → تخزين String غير مُفسَّر
لا تخلط بين تنسيق JSON ونوع عمود JSON. يمكنك إدراج بيانات منسّقة بصيغة JSON (عبر
JSONEachRow وغيرها) في أعمدة محددة النوع من دون استخدام نوع العمود JSON على الإطلاق. القرار هنا يتعلق بأنواع الأعمدة، لا بتنسيقات الإدخال.تفاصيل النهج
أعمدة محددة النوع
Array وTuple وNested.
الاعتبارات: تتطلب تغييرات المخطط استخدام ALTER TABLE. كما تُهمَل الحقول غير المتوقعة بصمت عند الإدراج ما لم يتم تحديث المخطط.
الإعداد والتحقق والمحاذير
الإعداد والتحقق والمحاذير
الإعدادالتحققانتبه إلى
- إذا أدرجت بيانات JSON باستخدام
JSONEachRowوكان JSON يحتوي على حقول غير موجودة في المخطط، فإن ClickHouse يتجاهلها بصمت افتراضيًا. اضبطinput_format_skip_unknown_fieldsعلى0إذا كنت تريد ظهور أخطاء بدلًا من ذلك.
هجين (أعمدة محددة النوع + JSON)
الإعداد والتحقق والمحاذير
الإعداد والتحقق والمحاذير
الإعدادالتحققانتبه إلى
- استخدم تلميحات الأنواع لمسارات JSON التي تعرفها مسبقًا. تتجاوز هذه التلميحات عمود التمييز وتخزّن المسار مثل أي عمود محدد النوع عادي، بالأداء نفسه ومن دون عبء إضافي.
- استخدم
SKIPأوSKIP REGEXPللمسارات التي لا تستعلم عنها مطلقًا (مثل بيانات debug الوصفية ومعرّفات tracing الداخلية) لتوفير مساحة التخزين وتقليل عدد الأعمدة الفرعية. - اضبط
max_dynamic_pathsبما يتناسب مع عدد المسارات الفريدة التي تستعلم عنها فعليًا. تعمل القيمة الافتراضية (1024) في معظم الحالات. خفّضها إذا كان القسم الديناميكي لديك محدودًا. - لا تضبط
max_dynamic_pathsعلى قيمة تتجاوز 10,000. فالقيم المرتفعة تزيد استهلاك الموارد وتقلل الكفاءة.
المفاتيح المنقوطةتُعامل المفاتيح التي تحتوي على نقاط (مثل
http.status_code) على أنها مسارات متداخلة افتراضيًا، لذا يُخزَّن {"http.status_code": 200} بالطريقة نفسها التي يُخزَّن بها {"http": {"status_code": 200}}. وهذا شائع في سمات OTel. استخدم تلميحات الأنواع للتحكم في كيفية تخزين المسارات المنقوطة، أو فعّل json_type_escape_dots_in_keys (25.8+).عمود JSON الأصلي
الإعداد والتحقق والمحاذير
الإعداد والتحقق والمحاذير
الإعداداستخدم تنسيق انتبه إلى
JSONAsObject عند إدراج مستندات JSON كاملة في عمود JSON. فهو يتعامل مع كل سطر إدخال على أنه كائن JSON كامل يُربَط بالعمود.التحقق- من دون تلميحات للأنواع، يستنتج ClickHouse الأنواع لكل مسار استنادًا إلى أول القيم التي يراها. فإذا وصلت
scoreعلى شكل"10"(سلسلة نصية) في سجل، و10(عدد صحيح) في سجل آخر، فسيُنشئ المسار discriminator column وتصبح الاستعلامات أبطأ. أضف تلميحات للمسارات ذات الأنواع المعروفة. - عندما يتجاوز عدد المسارات
max_dynamic_paths، تنتقل قيم overflow إلى بنية بيانات مشتركة مع تراجع في query performance. راقب ذلك باستخدامJSONDynamicPaths()، وأبقِ الحد أقل من 10,000. - يدعم كل مسار ديناميكي حتى
max_dynamic_types(القيمة الافتراضية 32) من data types المميزة. وإذا تجاوز مسار واحد هذا الحد، فستعود الأنواع الإضافية تلقائيًا إلى تخزين متغير مشترك. ونادرًا ما يكون هذا مهمًا إلا إذا كانت بياناتك تحتوي على أنواع شديدة التباين للحقل نفسه.
تخزين String غير مُفسَّر
JSONExtract)، وهذا يكون بطيئًا عند التوسّع.
الإعداد والتحقق والمحاذير
الإعداد والتحقق والمحاذير
الإعدادالتحققانتبه إلى
- إذا تغيّرت المتطلبات واحتجت لاحقًا إلى استعلامات على مستوى الحقول، فستحتاج إلى إنشاء table جديدة تضم columns محددة النوع أو JSON columns، ثم backfill للبيانات. إذا كان هناك أي احتمال لأن تستعلم عن حقول منفردة، فابدأ باستخدام النهج الهجين بدلًا من ذلك.
- تُحلِّل دوال
JSONExtractالسلسلة في كل query. هذا مقبول للاستكشاف المخصص، لكنه غير مناسب لـ dashboards في بيئة production أو workloads ذات QPS مرتفع. - فكّر في استخدام codecs للضغط (
ZSTD) على عمود String إذا كانت payloads الخاصة بـ JSON كبيرة، إذ يضغطها بكفاءة.
المقارنة
متى يكون Map خيارًا أفضل
Map(String, T) أبسط وأكثر كفاءة من عمود JSON. ومن الأمثلة الشائعة: الوسوم النصية (Map(String, String))، والمقاييس العددية (Map(String, Float64))، أو مفاتيح تفعيل الميزات (Map(String, Bool)).
Map التصفية على مستوى المفاتيح (tags['env'] = 'prod')، وتكلفة تخزينه أقل من JSON، كما يتجنب الكلفة الإضافية للأعمدة الفرعية في نوع JSON. لاحظ أن عمليات البحث عن المفاتيح تفحص الخريطة خطيًا افتراضيًا — وهذا مناسب لمجموعات الوسوم الصغيرة، ولكن إذا كانت خرائط Map تحتوي على أكثر من 100 مفتاح، ففكّر في استخدام تسلسل with_buckets. استخدم JSON عندما تكون القيم من أنواع مختلطة أو عندما تكون البنية متداخلة — واستخدم Map عندما تكون البيانات أزواج مفتاح-قيمة مسطحة ذات نوع قيم موحّد.
- استخدم JSON حيثما كان مناسبًا — متى تستخدم نوع عمود JSON بدلًا من الخيارات الأخرى
- مرجع نوع بيانات JSON — الصياغة الكاملة لتلميحات الأنواع، وSKIP، وmax_dynamic_paths، ودوال الاستبطان
- اختيار أنواع البيانات — إرشادات عامة لاختيار النوع المناسب
- A New Powerful JSON Data Type for ClickHouse — شرح متعمق لمعمارية تخزين نوع JSON
- مرجع تنسيقات JSON — تنسيقات الإدخال/الإخراج لبيانات JSON (JSONEachRow وJSONAsObject وما إلى ذلك)