مقدمة
قد تبدو عبارة صغيرة مثل index=True في تعريف حقل كخيار ثانوي لا يكلف شيئًا، لكنها في الواقع تشير إلى قرار بنيوي يؤثر في أداء النظام عند البحث والتصفية على مجموعات بيانات كبيرة.
هذا الدليل يشرح فكرة الحقل المفهرس داخل نموذج بيانات أودو، التأثير في قاعدة البيانات، ومتى يكون من المنطقي إضافته أثناء تطوير موديلات مخصصة أو مراجعة تخصيصات قائمة. فهم هذه الجزئية يساعدك على اتخاذ قرارات أداء أفضل.
ما هو الحقل المفهرس في أودو؟
عندما ترى في تعريف حقل داخل ORM الخاص بأودو الوسيطة index=True، فهذا يعني أن أودو سيطلب من PostgreSQL إنشاء فهرس (عادةً B-tree) على العمود المقابل عند تثبيت أو تحديث الموديل.
مثال عملي في كود بايثون يوضح مكان إسناد هذه الخاصية.
class SaleOrder(models.Model):
_name = 'sale.order'
reference = fields.Char(string='Reference', index=True)
state = fields.Selection([...], index=True)
partner_id = fields.Many2one('res.partner', index=True)
من وجهة نظر المستخدم لا يوجد أي أثر مرئي للفهرس: النموذج والقوائم تبدو كما هي. الفهرسة تعمل خلف الكواليس في مستوى قاعدة البيانات فقط.
النتيجة العملية الوحيدة هي السرعة. الفهرس يسمح لPostgreSQL إيجاد الصفوف المطابقة بسرعة بدلاً من فحص الجدول كله، وفرق الأداء يصبح ملحوظًا عندما تكون الجداول بها عشرات أو مئات الآلاف من السجلات.
ما أنواع حقول أودو التي تقبل index=True
عمومًا الحقول البسيطة (السكالر) في ORM تدعم وسيلة index:
- Char و Text
- Integer و Float
- Date و Datetime
- Selection
- Many2one (شائعة جدًا للفهرسة)
- Boolean
الحقول العلائقية مثل One2many و Many2many لا تملك عمودًا مفردًا يفهرس بنفس الشكل، لذا لا يكون لـ index معنى عملي لها. أيضًا الحقول المحسوبة غير المخزنة لا يمكن فهرستها لأنها لا تولد عمودًا في قاعدة البيانات.
كيف يعمل هذا الحقل
عندما يُثبَّت أو يُحدَّث موديل، يقرأ أودو تعريفات الحقول ويزامن مخطط قاعدة البيانات؛ للحقل الذي يحتوي index=True سينفذ أودو أمر SQL لإنشاء فهرس على ذلك العمود.
بشكل افتراضي ينشئ PostgreSQL فهرسًا من نوع B-tree، وهذا مناسب لمعظم حالات المقارنات والبحث النطاقي والفرز التي تعتمد عليها أغلبية عمليات التصفية في أودو.
كيف يتفاعل ذلك مع ORM في أودو
عند تحويل نطاقات البحث (domains) من بايثون إلى استعلامات SQL، سيضع ORM شروط WHERE؛ إذا كان الحقل مفهرسًا يستطيع محرك قاعدة البيانات استخدام الفهرس لتسريع تنفيذ الشرط بدلاً من المسح الكامل.
أحد أشهر الأمثلة هو حقل Many2one مثل partner_id في أوامر المبيعات: تخزين معرف الشريك كقيمة صحيحة يؤدي لشرط WHERE عند تصفية أوامر لشريك معين، وفهرس هذا العمود يحول العملية إلى بحث سريع حتى مع حجم كبير من السجلات.
تأثير الفهارس على عمليات الكتابة
الفهرس له تكلفة: كل إدخال أو تعديل أو حذف يتطلب تحديث الفهارس المقابلة، مما يضيف زمنًا على عمليات الكتابة. لذلك لا ينبغي فهرسة كل حقل بلا تمييز على حساب أداء الإضافة والتعديل.
خيار index='trigram'
ابتداءً من أودو 16 يمكن أن تأخذ الخاصية قيمة 'trigram' لإنشاء فهرس GIN مع امتداد pg_trgm في PostgreSQL، ما يجعل البحث بنمط ILIKE الجزئي سريعًا—مفيد عند البحث بأجزاء من أسماء المنتجات أو الشركاء.
name = fields.Char(string='Product Name', index='trigram')
خيار متقدم يستخدمه أودو نفسه لحالات البحث النصي الجزئي المتكررة.
حالات عمل عملية
أمثلة عملية حيث يغير الفهرس تجربة المستخدم فعليًا.
1. إدارة المبيعات: تصفية العملاء حسب مدير المبيعات
في نظام CRM يجري المدراء بحثًا متكررًا حسب مالك الفرصة؛ حقل user_id مفهرس افتراضيًا في أودو، وأي حقل Many2one مخصص مشابه يُفضل فهرسته إذا سيُستخدم للتصفية.
2. المبيعات: البحث حسب حالة الطلب
حقل state في sale.order مفهرس لجعل تحميل القوائم حسب الحالة سريعًا—مجدي للشركات التي تعالج أحجامًا كبيرة من الطلبات.
3. المخزون: تتبع الحركات حسب المنتج
حركات المخزون تتراكم سريعًا؛ فهرس product_id على stock.move يجعل تقارير تتبع المنتج واستعلامات الحركات قابلة للاستخدام في مستودعات مزدحمة.
4. المحاسبة: تصفية قيود اليومية حسب الشريك
المحاسبون يبحثون عن قيود مرتبطة بعميل أو مورد محدد على مدار سنوات؛ فهرس partner_id على account.move.line يبقي التقارير مثل العملاء المستحقين سريعة.
5. موديلات مخصصة: حقول مرجعية للتتبع
في تطوير موديلات مخصصة، الحقول المرجعية أو رموز المشاريع التي سيبحث عنها المستخدمون كثيرًا يجب فهرستها للحفاظ على أداء قابلية البحث مع نمو البيانات.
إنشاء أو تخصيص حقل مفهرس
في بايثون (تطوير مودول مخصص)
إضافة index=True إلى تعريف الحقل في كود بايثون بسيطة: تمرر الوسيطة عند تعريف الحقل داخل الكلاس.
from odoo import models, fields
class ProjectTask(models.Model):
_inherit = 'project.task'
x_external_ref = fields.Char(
string='External Reference',
index=True,
help='Reference number from the external system'
)
بعد تعديل الكود قم بتحديث الموديل عبر odoo-bin -u your_module_name أو من واجهة التطبيقات؛ عندها سينشئ أودو الفهرس في قاعدة البيانات.
يمكن أيضًا تعديل تعريف حقل قائم بالوراثة لإضافة الفهرس، لكن هذه الطريقة تتطلب الحذر لتجنب تغيير سلوك الحقل الأصلي بطريق غير مقصود.
في Odoo Studio
Odoo Studio يسهّل إنشاء الحقول لغير المطورين، لكنه لا يعرض خيار تعيين الفهرس عند الإنشاء. الحقول المصنوعة عبر Studio لا تُنشأ عادةً مع index=True افتراضيًا.
إذا احتجت إلى فهرس لحقل أنشأته Studio، الحل الأنظف هو تحويل التخصيص إلى مودول بايثون وإضافة index=True هناك؛ عادةً يتولاها مطور أودو.
إضافة فهرس مباشرةً في PostgreSQL
أحيانًا في بيئة إنتاجية يحتاج مسؤول قاعدة البيانات لإضافة فهرس يدويًا دون ترقية الموديل، عبر أمر SQL لإنشاء الفهرس.
CREATE INDEX CONCURRENTLY idx_sale_order_partner_id
ON sale_order (partner_id);
الخيار CONCURRENTLY يقلل من قفل الجدول أثناء إنشاء الفهرس، لكنه يتطلب تنسيقًا مع تعريف الموديل لأن مزامنة الكود وقاعدة البيانات تبقى مطلوبة.
أفضل الممارسات
فهرس الحقول التي تظهر في نطاقات البحث
كلما استُخدم حقل بشكل متكرر في نطاقات البحث—قوائم التصفية، قواعد آلية أو مهام مجدولة—فهو مرشح جيد للفهرسة، خصوصًا Many2one وحقل الحالة والحقول المرجعية.
اتباع اتفاقيات أودو نفسها
مصدر جيد لاتخاذ قرار هو مراجعة تعريفات الحقول في موديلات أودو القياسية مثل sale.order وaccount.move وstock.move؛ خيارات الفهرسة هناك مبنية على أنماط استخدام فعلية.
فهرس دائمًا حقول Many2one في الموديلات ذات الحجم الكبير
للموديلات التي تتراكم فيها سجلات كثيرة بمرور الوقت، فهرس حقول Many2one المستخدمة للتصفية يكسبك أداء قراءة أفضل بفرق ملحوظ ويعوض عادةً تكلفة كتابة الفهارس.
فكر في فهرس الترايغرام للنصوص
في أودو 16+ إذا كان المستخدمون يبحثون بكتابة أجزاء من النص في حقل Char مثل أسماء المنتجات، فكر في index='trigram' لأن هذا الفهرس مُصمَّم للبحث الجزئي باستخدام ILIKE.
التأكد من أن الفهرس يُستخدم فعلاً
بعد إضافة فهرس، شغّل EXPLAIN ANALYZE على الاستعلام لترى ما إذا كان مخطط التنفيذ يستخدم الفهرس. أحيانًا الجدول صغير جدًا أو طريقة كتابة الشرط لا تتوافق مع نوع الفهرس، فيُفضل المخطط المسح التسلسلي.
وثق قراراتك بشأن الفهرسة
اترك تعليقًا مختصرًا في الكود يوضح سبب إضافة الفهرس؛ هذا يساعد المطورين المستقبليين على فهم الغرض وتجنب إزالته عن طريق الخطأ أثناء إعادة هيكلة.
المزالق الشائعة
تجنّب فهرسة كل الحقول افتراضيًا
خطأ شائع هو إضافة index=True لكل حقل بدافع الحذر؛ لكل فهرس تكلفة تخزين وزمن إضافي على عمليات الكتابة، لذا الفهرسة غير المبررة قد تُبطئ النظام.
الفهرسة على الجداول الصغيرة
الجداول ذات بضع مئات من الصفوف غالبًا ما تكون أسرع بمسح تسلسلي بدلاً من استخدام فهرس؛ لذلك فهرسة جداول lookup صغيرة أو موديلات نادرة الاستخدام لا تضيف فائدة عملية.
نسيان ترقية الموديل بعد إضافة index=True
إضافة الوسيطة في كود بايثون وحدها لا تنشئ الفهرس فعليًا في قاعدة البيانات—لا بد من ترقية الموديل عبر -u module_name أو من الواجهة، وإهمال ذلك يسبب التباسًا أثناء التطوير.
توقع فائدة الفهارس في كل أنواع ILIKE
فهرس B-tree العادي لا يساعد على استعلامات ILIKE '%كلمة%' ذات البدايات المتغيرة؛ لا يمكن استخدام B-tree مع بادئة وايلدكارد في البداية، لذا للبحث الجزئي استخدم index='trigram' أو حلول البحث النصي الكامل.
عدم مراعاة الحقول المحسوبة المخزنة
الحقول المحسوبة المخزنة (store=True) تولد أعمدة فعلية ويمكن فهرستها، وغالبًا يُغفل عنها بينما يمكن أن تحسّن أداء الفلاتر والتقارير إذا استخدمت بكثرة.
خلاصة
خاصية index=True عنصر بسيط في تعريف الحقل لكنه يؤثر فعليًا في أداء قاعدة البيانات مع نمو البيانات؛ الاستخدام الحكيم يحافظ على قوائم وتقارير سريعة، والاستخدام العشوائي يضيف عبئًا دون فائدة.
الخلاصة: فهرس الحقول التي تُستخدم بشكل متكرر في نطاقات البحث، خصوصًا Many2one في موديلات عالية الحجم؛ اتبع اختيارات أودو القياسية وتجنّب الفهرسة غير المبررة على الجداول الصغيرة. وعلى أودو 16+ فكّر في index='trigram' للنصوص التي يُبحث عنها جزئيًا.
من الأسهل اعتماد استراتيجية فهرسة سليمة منذ بداية مشروع التطوير من محاولة إصلاح استعلامات بطيئة في بيئة الإنتاج لاحقًا.
تعمل على تنفيذ أودو؟
في Dasolo نساند الشركات في تنفيذ وتخصيص وتحسين أودو. سواء كنت تبني موديلات مخصصة، تعمل على تحسين أداء نظام قائم، أو تخطط لمشروع أودو جديد، نقدم خبرة تقنية عملية في كل مهمة.
إذا تواجه استعلامات بطيئة، تخصيصات معقدة، أو تحتاج إرشادًا في أفضل ممارسات تطوير أودو، نحن هنا للمساعدة. تواصل مع فريق Dasolo وأخبرنا بما تعمل عليه.