PostgreSQL
قاعدة بيانات مفتوحة واسعة الانتشار. كثير من الأنظمة الداخلية تعيش فيها، وأسئلة كثيرة إجاباتها صف واحد فيها.
قاعدة بيانات مفتوحة واسعة الانتشار. كثير من الأنظمة الداخلية تعيش فيها، وأسئلة كثيرة إجاباتها صف واحد فيها.
ماذا يحمل PostgreSQL، ولماذا يهمّ ذلك هنا
ليست كل الإجابات في نظام له واجهة. كثير من المؤسسات تدير أنظمة داخلية بُنيت خصيصاً، وبياناتها موجودة في قاعدة بيانات دون أي شاشة سهلة للسؤال عنها.
وهذا يجعل الوصول إليها محصوراً في من يستطيع كتابة استعلام، وهو عدد قليل دائماً. فتتحول أسئلة بسيطة إلى طلبات تنتظر في طابور فريق تقني.
والربط هنا يحلّ ذلك بشرط أساسي: نطاق محدد صراحة. قراءة فقط، وعلى جداول وحقول محددة، وبما يخدم قائمة أسئلة معروفة — لا وصولاً عاماً للقاعدة.
- بيانات التطبيقات — ما تسجّله الأنظمة المبنية عليها.
- البيانات المرجعية — القوائم التي تعتمد عليها أنظمة أخرى.
- السجلات التشغيلية — المعاملات والأحداث والحالات.
- البيانات التاريخية — ما جرى سابقاً، وكثيراً ما لا يوجد في مكان آخر.
- العروض — الشرائح المنتقاة التي عرّفها فريقكم مسبقاً.
أسئلة يجيب عنها إلبي من PostgreSQL
ما حالة هذا السجل؟
السجل من عرض محدد، مصاغاً بجملة لا بصف.
كم عدد كذا؟
إحصاء ضمن النطاق المسموح.
متى حدث هذا؟
التاريخ المسجّل كما هو.
من المسؤول عن هذا؟
الحقل المسجّل، حيث يكون عرضه مناسباً.
ما آخر تحديث؟
الطابع الزمني المسجّل.
هل هذا موجود؟
بحث ضمن النطاق المسموح فقط.
كيف يقرأ إلبي من PostgreSQL
- دور دخول لا يرث شيئاًيستخدم الربط دور دخول (login role) خاصاً به، له صلاحية CONNECT على قاعدة واحدة وUSAGE على مخطط (schema) واحد يضم العروض المتفق عليها. ولأنه ليس عضواً في أي دور من أدوار التطبيق، فلا يرث شيئاً لم يُمنح له صراحة.
- SELECT على عروض في مخطط مخصّصتقع العروض في مخطط خاص بها، ولا تكشف إلا الأعمدة التي يحتاجها كل جواب. يحصل الدور على SELECT على تلك العروض ولا شيء على الجداول تحتها، وتُترك عمداً الأدوار المدمجة الواسعة مثل pg_read_all_data.
- قراءة فقط على مستوى الدور أيضاًضبط default_transaction_read_only وstatement_timeout على الدور يضيف حاجزاً ثانياً خلف الصلاحيات، في وجه صلاحية مُنحت خطأً أو استعلام يطول أكثر مما ينبغي لأي بحث.
- أمان مستوى الصفوف للإجابات الشخصيةحين يجب أن تقتصر الإجابات على سجلات السائل نفسه، يستطيع أمان مستوى الصفوف (row-level security) في PostgreSQL فرض ذلك داخل القاعدة، إضافة إلى ما يفرضه المساعد. والعروض تعمل عادة بصلاحيات مالكها، ولذلك تتيح الإصدارات الحديثة تعريفها بخيار security_invoker لتنطبق تلك السياسات على القارئ.
- استعلامات بمعاملات على نسخة احتياطيةتجري الاستعلامات عبارات بمعاملات، ويُفضَّل أن تكون على نسخة احتياطية ساخنة (hot standby). والنسخة الاحتياطية للقراءة فقط بطبيعتها، وإن كان الاستعلام الطويل عليها قد يُلغى حين يتعارض مع النسخ المتماثل، وهذا سبب إضافي لإبقاء الاستعلامات قصيرة.
- القيم تتحول إلى لغةقيم الأنواع المعدّدة (enum) والرموز والطوابع الزمنية تُصاغ جملاً عربية أو إنجليزية لا كما هي مخزّنة. وأعمدة JSON يُستحسن تفكيكها داخل العرض، ليقرأ المساعد حقولاً مسمّاة بدل أن يفسّر مستنداً.
الأدوار والصلاحيات وما يبقى ملككم
الوصول قراءة فقط بالصلاحية وبإعداد الدور معاً: SELECT على عروض مسمّاة، مع تفعيل default_transaction_read_only. والكتابة مكانها التطبيقات التي تملك البيانات.
والعروض تحدد ما يستطيع الدور بلوغه. وهوية السائل تحدد الإجابات التي يحصل عليها، ويستطيع أمان مستوى الصفوف فرض القاعدة نفسها داخل القاعدة للبيانات الخاصة بكل عميل.
وبيانات الاعتماد دور دخول تنشئونه، يتحقق من هويته بكلمة مرور SCRAM أو بشهادة عميل، ولا يسمح له ملف pg_hba.conf بالدخول إلا من عنوان الربط. وتحويل الدور إلى NOLOGIN أو تغيير كلمة مروره ينهي الوصول من جهتكم دون تدخل منا.
والصفوف المجلوبة لاستعلام ما تخدم الرد الذي جُلبت له وحده. ويُتلف محتوى الرسائل خلال 24 ساعة، عادةً مع نهاية المحادثة، ولا تعالجه أي خدمة ذكاء اصطناعي خارجية.
وتستطيع إضافة pgAudit تسجيل قراءات الدور على مستوى العبارة أو الكائن، أو يمكن تفعيل تسجيل العبارات لهذا الدور وحده. وفي الحالتين يبقى سجل ما استُعلم عنه في سجلاتكم أنتم.
وإن توقفت النسخة الاحتياطية، أو رُفض الدور، أو بلغت عبارة حدها الزمني، يقول المساعد إنه لم يصل إلى الجواب ويعرض التحويل إلى موظف. وانتهاء المهلة لا يُعرض أبداً على أنه «لا توجد سجلات».
ما الذي يحلّ محلّه ربط PostgreSQL
ما يحلّ محلّه هذا هو طلب استعلام من فريق تقني. الموظف الذي يحتاج رقماً بسيطاً يفتح طلباً، وينتظر، ويحصل على جدول يحتاج تفسيراً.
وهذه الدورة تستهلك وقت الطرفين وتؤخر قرارات بسيطة. والأسوأ أنها تتكرر: السؤال نفسه يُطلب شهرياً من أشخاص مختلفين.
والاتصال يزيلها للأسئلة المعروفة المتكررة، ويترك التحليل المعقّد لمن يجيده — وهو ما ينبغي أن يعمل عليه الفريق التقني أصلاً.
أي الفرق تعتمد على ربط PostgreSQL
الأنظمة الداخلية
بيانات بلا واجهة سهلة للسؤال عنها.
التقنية
تقليل طلبات الاستعلام المتكررة.
العمليات
أرقام يومية دون انتظار.
المالية
أرقام مسجّلة بصلاحية محددة.
الجودة
متابعة مؤشرات مسجّلة.
الإدارة
أرقام الأنظمة الداخلية دون طلب استعلام.
كيف تستفيدون فعلاً من PostgreSQL
ابدأوا بالطلبات التي يجيب عنها فريقكم التقني اليوم بكتابة استعلام يدوياً. عدُّها لبضعة أسابيع يكشف عادة مجموعة صغيرة من الأشكال — حالة بحسب مرجع، وعدد بحسب فترة، وقائمة بما هو معلّق — وكل شكل منها يصبح عرضاً واحداً.
وصمّموا العروض حول السؤال لا حول الجدول. العرض الذي يربط ويرشّح ويسمّي الأشياء بلغة العمل — open_orders_by_customer بدل ربط خام بين جداول — يجعل الاستعلام بسيطاً، ويتيح لمن لا يقرأ SQL أن يراجعه.
وقرّروا مبكراً هل بعض الإجابات خاصة بكل عميل. فإن كانت كذلك، فأمان مستوى الصفوف يستحق التخطيط من البداية، لأنه يجعل القاعدة نفسها ترفض الصفوف الخطأ بدل الاعتماد على صحة كتابة كل عرض.
ما الذي يتطلبه ربط PostgreSQL
- كتابة الأسئلة عروضاًكل سؤال متكرر يصبح عرضاً في مخطط مخصّص، يراجعه من يعرف البيانات، ويُسمّى بحيث يفهم غير المتخصص ما يعيده.
- إنشاء الدورCREATE ROLE مع LOGIN، وكلمة مرور قوية أو شهادة، وCONNECT على القاعدة، وUSAGE على مخطط العروض، وSELECT على العروض. لا شيء على المخطط العام، ولا عضوية في أي دور.
- تقييد مصدر الاتصالأضيفوا سطراً في pg_hba.conf لا يقبل الدور إلا من عنوان الربط، بمصادقة SCRAM أو بالشهادة، وإلى القاعدة التي يحتاجها وحدها.
- ضبط الحواجزاضبطوا default_transaction_read_only وstatement_timeout على الدور، وقرّروا هل يسجّل pgAudit نشاطه من اليوم الأول.
- توجيهه إلى نسخة احتياطيةحيث يوجد نسخ متدفق (streaming replication)، استخدموا نسخة احتياطية ساخنة للاستعلامات، واتفقوا لكل سؤال على المدى المقبول لتأخر الجواب عن القاعدة الرئيسية.
- اختبار الرفضاستعلموا عن جدول مباشرة، واسألوا عن سجل عميل آخر، وشغّلوا استعلاماً مصمماً ليتجاوز مهلته. ينبغي أن يفشل كلٌّ منها بوضوح وأن يُبلَّغ عنه كفشل، لا كنتيجة فارغة.
التحكم بالصفوف والبيانات الشخصية في PostgreSQL
يمنحكم PostgreSQL موضعين للتحكم في البيانات الشخصية: العرض، الذي يحدد أيّ الأعمدة موجودة للربط أصلاً، وأمان مستوى الصفوف، الذي يحدد أيّ الصفوف يمكن أن يعيدها استعلام بعينه. وبموجب نظام حماية البيانات الشخصية في المملكة، استخدام الاثنين في الإجابات الموجّهة للعملاء يجعل إثبات تقليل البيانات أمراً سهلاً.
وموقع البيانات يتبع الخادم — بنيتكم التحتية، أو مزوّد استضافة، أو خدمة PostgreSQL مُدارة في منطقة اخترتموها. والربط يقرأ البيانات في مكانها؛ دوّنوا الموقع بجانب قائمة العروض.
وصلاحيات الدور، وسطره في pg_hba.conf، وسجل pgAudit إن فُعّل، تجيب معاً عن أسئلة المراجع — ماذا يستطيع أن يقرأ، ومن أين، وماذا قرأ — من أنظمتكم أنتم.
طرق أخرى تصل بها بيانات PostgreSQL إلى الناس
يصل الفنيون إلى PostgreSQL عبر أدوات مثل psql أو pgAdmin، والمحللون عبر أدوات ذكاء الأعمال التي تقرأ من نسخة متماثلة. وكلاهما يخدم مستخدميه جيداً، ويترك الجميع غيرهم يسألون أولئك المستخدمين.
وبعض الفرق تكشف العروض كواجهة برمجية بأداة مثل PostgREST، التي تبني واجهة REST من المخطط وتعتمد على أدوار PostgreSQL وأمان مستوى الصفوف في ضبط الوصول. وهو نمط مرتب، لكنه يحتاج بعد ذلك واجهة يستطيع الناس طرح أسئلتهم عليها فعلاً.
وترك نموذج لغوي يكتب SQL بحرية على المخطط أمر يتكرر في العروض التوضيحية. أما على بيانات الإنتاج فيجمع أوسع وصول مع أقل استعلامات قابلية للتوقع، ولهذا يعتمد هذا الربط على عروض ثابتة بمعاملات.
والخطأ المتكرر منح pg_read_all_data، أو العضوية في دور التطبيق نفسه، لأنه كان أسرع. وكلاهما يحوّل الربط المحدود بهدوء إلى نسخة من صلاحيات القراءة الخاصة بالتطبيق.
ما الذي تراه المؤسسات عادة
أسئلة متكررة عن ربط PostgreSQL
لا. الدور لا يملك غير SELECT على عروض محددة، وهو مضبوط أيضاً على default_transaction_read_only.
لا. النطاق يُحدَّد صراحة، ونوصي باستخدام طبقة عرض تحدّد ما يُقرأ بدقة بدل منح وصول لجداول كاملة.
الاستعلامات محدودة النطاق، والحمل يُقاس في الاختبار على بياناتكم قبل الإطلاق لا يُفترض.
ما تسمحون به فقط. الأعمدة الحساسة تبقى خارج العروض، ويمكن لأمان مستوى الصفوف أن يحصر كل عميل في سجلاته.
الصلاحية تُربط بهوية السائل. وقاعدة البيانات لا تحمل صلاحيات المستخدمين عادة، فهذا الربط يُصمَّم صراحة.
بإيقاف حساب الخدمة، وهو منفصل لهذا السبب تحديداً.