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

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

برمجيات مخصّصة بـ Next.js و PostgreSQL

ما يغيّره اختيار PostgreSQL في بناء Next.js - الضمانات التي يفرضها، والبحث الذي لم يبقَ له حاجة لخدمة، والفخّ الذي يقع فيه كل فريق مرة.

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

ضمانات لا يستطيع التطبيق نسيانها

أقوى حجّة لقاعدة بيانات علائقية في البرمجيات المخصّصة لا علاقة لها بالأداء.

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

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

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

ما يحذفه ذلك من الكود

كل واحد من تلك القيود كود تحقّق لا تكتبونه ولا تختبرونه ولا تحتاجون تذكّره عند إضافة سابع طريقة لإنشاء سجل.

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

JSONB، وأين الخط

بعض البيانات تقاوم المخطّط فعلًا. حمولة webhook من طرف ثالث. نموذج يهيّئ العميل حقوله. إعدادات لكل عميل تختلف بين عميل وآخر.

وPostgreSQL يعامل ذلك بصدق: يُخزَّن JSONB بكفاءة ويُستعلَم بمعاملات حقيقية ويُفهرَس بـ GIN، فتكون البيانات غير المبنيّة خيارًا من الدرجة الأولى لا حلًّا ملتويًا.

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

البحث، بلا نظام ثانٍ

قسم كبير من التطبيقات يضيف خدمة بحث وخط مزامنة واعتمادًا تشغيليًا ليفعل شيئًا تستطيع قاعدة البيانات فعله أصلًا.

والبحث في النص الكامل في PostgreSQL فيه تجذير وترتيب وتهيئات لعدة لغات، ويُفهرس جيدًا. ومع بضع مئات آلاف السجلات يكون سريعًا، وله ميزة كبيرة هي أن نتائج البحث لا يمكن أن تكون قديمة، لأنه لا شيء يُزامَن.

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

الفخّ الواحد، وكيف يُعالَج

كل فريق يلقاه مرة. تطبيق Next.js على بيئة بلا خوادم يفتح اتصالًا بقاعدة البيانات لكل نسخة، وPostgreSQL يقبل عددًا ثابتًا. وتحت الزيارات لا يصير التطبيق أبطأ - بل يبدأ برفض الاتصالات، وهذا يُقرأ كفشل قاعدة بيانات وهو خطأ في الإعداد.

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

ويُحسَم ذلك في الأسبوع الأول في هذه الأعمال، وهو الفرق بين قيد معروف وحادثة.

كيف يسير العمل

على مراحل، كل واحدة تُثبَّت كتابةً قبل بدئها وتنتهي بشيء منشور تستطيعون استخدامه. والمرحلة الأولى تأخذ مسارًا واحدًا من أوله إلى آخره بدل مخطّط عدة مسارات، لأن ذلك ما يحسم المخطّط على بيانات حقيقية.

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

ما تحصلون عليه

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

ومعه: ملاحظة مكتوبة عن نموذج البيانات ولماذا هو بهذا الشكل، والفهارس ولماذا كل واحد منها، وإعداد التجميع، والقيود مع سطر لكل واحد يوضح ما يمنعه. وهذا الأخير هو الوثيقة التي يعود إليها الناس فعلًا، لأن قيدًا لا يفهمه أحد قيدٌ يُزيله أحد في النهاية.

متى لا يكون PostgreSQL هو الجواب

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

وإن كان الحمل في حقيقته ذاكرة مؤقتة أو طابورًا، فليكن ذاكرة مؤقتة أو طابورًا. يستطيع PostgreSQL كليهما بشكل مقبول، وليس مصنوعًا لأي منهما.

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

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

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

الأسئلة الشائعة

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