PostgreSQL / المتقدم: الأدلة والتشغيل الموثوق / الدرس 14
بيانات JSONB واستراتيجيات الفهرسة
احفظ بيانات طرد مرنة بحدود علاقية مكتوبة الأنواع، وميز json عن jsonb والمسار المفقود عن JSON null والفهرسة حسب المعامل.
في هذه الصفحة
أهداف الدرس
- شرح تمثيل JSON ومعاملات الاستخراج.
- اختيار فهرس قيمة أو GIN وفق المعاملات الفعلية.
JSONB ليست صيغة ثنائية عامة قابلة للتبادل
تحفظ json النص والمسافات وترتيب المفاتيح، بينما تخزن jsonb تمثيلاً مفككاً وتطبع هذه التفاصيل وتبقي آخر مفتاح مكرر. ليست صيغة MySQL الثنائية أو اسم MariaDB البديل للنص. استخدمها لمعالجتها وفهرستها، واحفظ الأصل منفصلاً عند حاجة الأثر الدقيق. لا تثبت صحة JSON وجود حقل أو نوعه ومجاله التجاريين.
اختر استخراج JSON أو النص بوعي
تعيد -> قيمة JSON وتعيد ->> نصاً يصلح للتحويل المقصود. تستخرج العينة Harbor ووزناً دقيقاً 2.50 وتفحص الاحتواء. قد يعيد المسار الغائب SQL NULL، وJSON null قيمة مستقلة. لا تقارن الوزن نصياً وتفترض ترتيباً عددياً. عالج التحويل غير الصحيح كبيانات خاطئة لا حذف صامت من التقرير.
SELECT '{"carrier":"Harbor","kg":2.5}'::jsonb ->> 'carrier' AS carrier,
('{"carrier":"Harbor","kg":2.5}'::jsonb ->> 'kg')::numeric(6,2) AS kg,
'{"carrier":"Harbor","kg":2.5}'::jsonb @> '{"carrier":"Harbor"}'::jsonb AS matches;
carrier | kg | matches
Harbor | 2.50 | true
قد يعرض psql true كـ t؛ تُشتق القيم مباشرة من الوثيقة.
أبقِ الحقائق المرجعية مقيدة
تستحق الهوية والمفاتيح والمال كثير الربط أعمدة مكتوبة الأنواع. تحمل jsonb بيانات اختيارية ولا تلغي القيود وتطور المخطط. تحقق من الحقول وارفض المفاتيح المكررة قبل التحليل إن حظرها العقد؛ لا يسترجع فحص لاحق مفاتيح طُبعت واختفت. وثق اختلاف الغياب وJSON null وSQL NULL والنص الفارغ.
طابق فئة المعامل مع الاستعلام
يدعم GIN الافتراضي معاملات احتواء ووجود موثقة. تدعم jsonb_path_ops مجموعة أضيق بخصائص أخرى ولا تضمن كل بحث ? للوجود. يقترح المثال GIN للاحتواء وB-tree تعبيريّاً للشركة. كلاهما مرشح تدريبي، واختر بالدليل وحجم الوثائق والكتابة والخطة.
CREATE INDEX ix_meta_document
ON quay_lab.parcel_meta USING gin (payload);
CREATE INDEX ix_meta_carrier
ON quay_lab.parcel_meta ((payload ->> 'carrier'));
EXPLAIN SELECT parcel_id FROM quay_lab.parcel_meta
WHERE payload @> '{"carrier":"Harbor"}'::jsonb;
قد يتأهل الاستعلام لـ GIN الافتراضي، وقد تفضل الخطة مساراً آخر حسب العينة.
تبقى الوثيقة ضمن تزامن الصف
لا يعطي تحديث مسار صغير قفلاً مستقلاً لكل حقل؛ تنسق تغييرات الصف نفسه على مستوى الصف. قد تضخم الوثائق الكبيرة الكتابة وWAL والتنظيف. أضيفت JSON_TABLE في 17 وjsonb في 9.4، فراجع الدليل المثبت واختبر الدلالات عند النقل. لا يثبت اسم JSON المشترك توافق التخزين أو null أو المفاتيح المكررة.
الأخطاء الشائعة وإصلاحها
invalid input syntax for type numeric (22P02)
- لماذا يحدث؟
- لا تحقق القيمة النصية عقد العدد المتوقع.
- كيف تصلحه؟
- تحقق من شكل المصدر ونوعه وحول المقبول فقط.
- كيف تتجنب تكراره؟
- اختبر النوع الخاطئ والغياب وnull عند الدخول.
لا يخدم GIN المعامل المتوقع
- لماذا يحدث؟
- لا تدعم الفئة البحث أو يختلف الشرط.
- كيف تصلحه؟
- افحص المعاملات والتعبير المفهرس والخطة.
- كيف تتجنب تكراره؟
- اختر الفئة من المعامل لا اسم JSON وحده.
تختفي مفاتيح JSON الأصلية المكررة
- لماذا يحدث؟
- أبقت jsonb آخر قيمة مكررة فقط.
- كيف تصلحه؟
- ارفض الالتباس قبل التحويل أو احفظ النص الأصلي.
- كيف تتجنب تكراره؟
- حدد الأثر وقواعد التكرار عند الإدخال.
اختبر فهمك
1. تحوي وثيقة الوزن "100" وأخرى "9" كسلسلتين. وضح تقريراً عددياً صحيحاً.
اعرض الحل المشروح
قد يرتب النص 1 قبل 9، فاستخرج بـ ->> وتحقق وحول إلى numeric محدودة. حدد عرض الغياب والخطأ ولا تجعله صفراً بصمت. قد يلائم الوزن المرجعي عموداً عددياً مقيداً.
2. لماذا ليست jsonb_path_ops أفضل تلقائياً لحمل يجمع الاحتواء ووجود المفاتيح؟
اعرض الحل المشروح
تختلف المعاملات المدعومة والسلوك. طابق كل شرط بالقدرات وقارن الخطط وكلفة التخزين والكتابة. قد تفيد فئة أضيق الاحتواء ولا تدعم معامل وجود لازم فيغيب مسار الوصول المتوقع.
أهم ما تعلمته
- تطبع JSONB الوثائق وتبقى الصحة التجارية عقداً منفصلاً.
- افهرس JSON وفق المعامل ودلالة القيمة.