تخطَّ إلى المحتوى

تطوير برمجيات مخصّصة

برمجيات مخصّصة بـ Laravel و PostgreSQL

ما يمنحه PostgreSQL لبناء Laravel ولا يمنحه MySQL - ترحيل يرتدّ عند فشله، وضمانات لا يستطيع Eloquent تجاوزها، وتقارير بلا قاعدة بيانات ثانية.

Laravel يعمل على الاثنتين، فاختيار PostgreSQL قرار لا إعداد افتراضي - ويستحق التحديد ما الذي يمنحه، لأن المقارنات المتاحة تتحدّث عن القياسات ولا تتحدّث تقريبًا عمّا يحدث فعلًا بعد ظهر الخميس أثناء نشر.

ترحيل Laravel الفاشل يرتدّ

هذا هو الفرق الذي يغيّر سلوك الفريق، وهو الذي يذكره أحد نادرًا.

يطبّق PostgreSQL تغييرات المخطّط معاملاتيًا. فترحيل بست عبارات يفشل في الرابعة يترك قاعدة البيانات كما كانت تمامًا. لا شيء نصفيّ، ولا شيء يُفَكّ، والترحيل يمكن تصحيحه وتشغيله مرة أخرى.

أما MySQL فلا. العبارات الثلاث الأولى مطبّقة، والترحيل مسجّل كأنه لم يعمل، وعلى أحد الآن أن يثبت يدويًا أي نصف منه موجود. في الإنتاج، تحت ضغط الوقت، والنشر نصفه قائم.

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

قيود لا يستطيع Eloquent تجاوزها

القاعدة المفروضة في موديل تصمد للكود الذي يمرّ بالموديل.

ولا تصمد لتحديثة جماعية. ولا لنداء من query builder يكتب في الجدول مباشرة، وكل قاعدة كود فيها واحد في مكان ما. ولا لأمر الكونسول الذي كتبه أحدهم في التاسعة مساءً لإصلاح مشكلة بيانات، ولا للاستيراد الذي يعمل مرة كل ربع ولم يراجعه أحد.

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

ويضيف PostgreSQL اثنين يهمّان عمليًا. فقيد الاستبعاد يرفض حجزًا يتقاطع نطاق تاريخه مع حجز قائم للمورد نفسه، فيُغلق تنازعًا يصعب فعلًا إغلاقه في PHP. والفهرس الجزئي يغطّي الصفوف الجديرة بالتغطية وحدها، فلا يدفع استعلام على الأوامر المفتوحة كلفة خمس سنوات من المغلقة.

JSONB، وأين ينبغي أن يبدأ العمود

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

وPostgreSQL يعالج ذلك جيدًا لا على مضض - يُخزَّن JSONB مضغوطًا ويُستعلَم بمعاملات حقيقية ويُفهرَس بـ GIN ويُحوَّل بنظافة إلى خصيصة Eloquent. قرار تصميم معقول لا تراجع.

والانحدار تدريجي والقصة نفسها دائمًا. إضافة مفتاح إلى JSON لا تحتاج ترحيلًا ولا تجلب مراجعة، فهناك تبدأ الحقول بالذهاب. وفي السنة الثانية لا يستطيع أحد الإجابة عن سؤال حول البيانات دون قراءة PHP، وإخراج حقل إلى عمود يعني كتابة ترحيل يحلّل ثلاث سنوات من صفوف غير متّسقة الشكل.

والاختبار الذي يمنع ذلك: إن كنتم ستُصفّون أو ترتّبون أو تربطون أو تقرّرون به يومًا، فهو عمود. وكل ما عداه يمكن أن يسكن JSONB، وينبغي أن يسكنه.

تقارير بلا قاعدة بيانات ثانية

كثير جدًا من تطبيقات Laravel يجرّ آلاف الصفوف إلى PHP ويدور عليها لإنتاج رقم، لأن الاستعلام الذي يفعل ذلك في SQL بدا غير مألوف.

دوال النوافذ تجعل المجاميع الجارية والترتيبات ومقارنات الفترات استعلامًا واحدًا. وتعبيرات الجداول المشتركة تجعل حسابًا متعدّد الخطوات مقروءًا لا متداخلًا. والوصلات الجانبية تعالج شكل أفضل-ثلاثة-لكل-عميل الذي يصير حلقة N+1 بدونها. وكل واحدة منها تستبدل صفحة كود باستعلام تنفّذه قاعدة البيانات في مرور واحد.

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

ما يتغيّر فعلًا في Eloquent

صدقًا بشأن الاحتكاك، فهو موجود.

مقارنة النصوص تحسب حالة الأحرف، فـ where على بريد أو مرجع كان يعمل على MySQL قد يتوقّف عن المطابقة. وLIKE يحسب الحالة وILIKE هو الشكل الذي لا يحسبها، وذلك غير منقول بين القاعدتين - فالاستعلام المكتوب لإحداهما يحتاج انتباهًا في الأخرى.

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

والمفاتيح المتزايدة تلقائيًا تستخدم تسلسلات، وهذا يهمّ عند زرع بيانات بمعرّفات صريحة وعند نسخ صفوف بين البيئات. وكل ما كُتب SQL خامًا صار الآن خاصًّا بقاعدة بيانات، وهذه حجّة لإبقاء الـ SQL الخام في أماكن قليلة مسمّاة بدل تفريقه على الموديلات.

لا شيء من هذا عقبة. وكلها أرخص معرفةً في الأسبوع الأول من اكتشافها في مجموعة اختبارات تنجح محليًا وتفشل على staging.

شكل العمل مع Laravel و PostgreSQL، وأين يقع المخطّط فيه

في المرحلة الأولى، بقصد، إلى جانب المسار الذي يُبنى حوله - لا في وثيقة تصميم تسبقه ولا في مراجعة تليه.

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

وبقية العمل مُهيكلة كما في صفحة البرمجيات المخصّصة - مراحل، كل واحدة متّفق عليها كتابةً، وكل واحدة تنتهي بشيء منشور.

ما تحصلون عليه مع بناء بـ Laravel و PostgreSQL

إلى جانب التطبيق نفسه ومستودعه، الأشياء الخاصة بهذا الاختيار.

الترحيلات، وهي تاريخ قاعدة البيانات وسبب إمكان مراجعة تغيير المخطّط كأي كود آخر. وملاحظة عن نموذج البيانات تشرح الشكل بدل إعادة سرده. وجرد فهارس يقول لأي استعلام يوجد كل فهرس، حتى يعرف مطوّر قادم يحذف واحدًا ما الذي سيتباطأ. والقيود مشروحة بما تمنعه. واستعلامات التقارير مكتوبة ومُفسَّرة - فدالة نوافذ لا يفهمها أحد ستُستبدَل بحلقة في PHP أول مرة تحتاج تغييرًا.

متى يكون MySQL هو الجواب الأفضل

إن كانت استضافتكم أو فريق تشغيلكم أو سياسة عميلكم مبنية حول MySQL، فذلك قيد حقيقي لا نقص تقني. والفريق الذي يعرف كيف يستعيد قاعدة بيانات ويراقبها ويضبطها أثمن من مجموعة مزايا أفضل بقليل في قاعدة لم يشغّلها أحد.

وإن كان تطبيق قائم على MySQL وسليمًا، فترحيله من أجل المزايا أعلاه قلّما يستحق الاضطراب وحده. افعلوه إن وُجد سبب آخر لمسّ طبقة البيانات.

وإن كان التطبيق صغيرًا وغالبه قراءة والمخطّط مستقرًّا، فالفرق بين الاثنتين لن يكون ما يحدّد نجاح المشروع.

النطاق والشروط

نموذج التعاقد
نطاق محدّد يُتفق عليه كتابةً قبل بدء العمل. وليس أجرًا يوميًا مقابل قائمة مفتوحة.
السعر والمدة
يُحدَّدان لكل مشروع بعد تحديد النطاق، ويُعرضان معًا قبل بناء أي شيء.
ما نحتاجه منك
شخص واحد يملك اعتماد القرارات، ووصول إلى مستودعك ونظام تتبّع المهام لديك.
غير مشمول
كل ما يقع خارج النطاق المتفق عليه. فيصير نطاقًا مستقلًا لا أمر تغيير.
تكاليف الأطراف الثالثة
الاستضافة والتراخيص ورسوم الواجهات البرمجية واشتراكات الخدمات السحابية تتعاقد عليها وتدفعها أنت.
الفوترة
⁦Codefacture Yazılım A.Ş.⁩، تركيا. باليورو أو الدولار أو الجنيه الإسترليني عبر حوالة بنكية، دون ضريبة قيمة مضافة تركية على الخدمات المصدَّرة.

أسئلة متكررة

ما أكبر فرق عملي عن MySQL؟
الترحيل الفاشل لا يترك شيئًا وراءه. فـ PostgreSQL يطبّق تغييرات المخطّط داخل معاملة، فالترحيل الذي يفشل في عبارته الرابعة يرتدّ بالثلاث الأولى وتبقى قاعدة البيانات كما كانت تمامًا. أما في MySQL فالثلاث الأولى مطبّقة، والترحيل مسجّل كأنه لم يعمل، وعلى أحد أن يستنتج يدويًا أي نصف جرى - يوم جمعة عادةً، وفي الإنتاج عادةً. وهذه الخصيصة وحدها تغيّر مدى ثقة الفريق بالنشر.
هل يستطيع Eloquent تجاوز قيد في قاعدة البيانات؟
قيد قاعدة البيانات لا، ولهذا يوضع هناك. أما التحقّق في الموديل والـ observers والأحداث فتتجاوزها تحديثة جماعية، ونداء من query builder يتخطّى الموديل، وأي أمر كونسول كُتب على عجل. والفهرس الفريد والمفتاح الأجنبي وقيد التحقّق تصمد أمام كل ذلك لأنها مفروضة تحت التطبيق. وفي نظام يتعامل مع المال أو المخزون، الفرق بين خطأ لا يمكن أن يحدث وخطأ لم يحدث بعد.
هل JSONB عذر لعدم تصميم مخطّط؟
لا، والفخّ حقيقي بما يستحق التسمية. فـ JSONB مفيد فعلًا لبيانات لا تتحكّمون في شكلها - حمولة webhook، وإعدادات لكل عميل، ونموذج يهيّئه العميل - ومع فهرس GIN يُستعلَم جيدًا بدل أن يكون عمودًا للكتابة فقط. وما لا يجوز أن يصير إليه هو مكان الحقول الجديدة لأن الترحيل بدا جهدًا. والاختبار بسيط: إن كنتم ستُصفّون أو ترتّبون أو تربطون أو تقرّرون به يومًا، فهو عمود.
هل نحتاج قاعدة بيانات منفصلة للتقارير؟
عادةً لا، وذلك شيء أقلّ يُزامَن ويُشغَّل. فدوال النوافذ وتعبيرات الجداول المشتركة والوصلات الجانبية تتيح لاستعلام أن يفعل في قاعدة البيانات ما تفعله التطبيقات بجرّ آلاف الصفوف إلى PHP والدوران عليها. وتوجيهها إلى نسخة قراءة يبقيها بعيدة عن الحمل المعاملاتي. أما مستودع منفصل فيستحق موضعه عندما تتنازع التقارير فعلًا مع الإنتاج أو تمتدّ على عدة أنظمة، وهذا قياس لا افتراض.
هل نقرأ هذه بدل صفحة البرمجيات المخصّصة أم معها؟
معها. تلك الصفحة تتناول كيف يُحدَّد البناء ويُدار ويُسلَّم؛ وهذه تتناول فقط ما يغيّره اختيار قاعدة البيانات، لأن من يبحث عن فريق لـ Laravel و PostgreSQL يريد جواب ذلك السؤال لا السؤال العام. ولا يختلف شيء في الترتيب التجاري.
اتصل بنا+1 848 272 7583واتساب+90 850 308 5436البريدinfo@codefacture.comصفحة التواصل