قاعدة بيانات كائنات زوب

قاعدة بيانات كائنات Zope ( ZODB ) هي قاعدة بيانات كائنية التوجه لتخزين كائنات بايثون بشكل شفاف ودائم . وهي مضمنة كجزء من خادم تطبيقات Zope على الويب ، ولكن يمكن استخدامها بشكل مستقل عن Zope.

تشمل ميزات ZODB ما يلي: المعاملات، والسجل/التراجع، والتخزين القابل للتوصيل بشفافية، والتخزين المؤقت المدمج، والتحكم في التزامن متعدد الإصدارات (MVCC)، وقابلية التوسع عبر الشبكة (باستخدام ZEO ).

تاريخ

تم إنشاء قاعدة بيانات كائنات زوب (ZODB) بواسطة جيم فولتون من شركة زوب في أواخر التسعينيات. في البداية، كانت عبارة عن نظام كائنات ثابت بسيط (POS) أثناء تطوير برينسيبيا، والتي تطورت لاحقًا إلى زوب. أدى تغيير معماري كبير إلى إعادة تسمية النظام إلى ZODB 3. بعد ذلك، تم طرح ZODB 4 كمشروع قصير الأجل يهدف إلى إعادة تنفيذ حزمة ZODB 3 بالكامل باستخدام لغة بايثون.

تطبيق

الأساسيات

يخزن ZODB كائنات بايثون باستخدام نسخة موسعة من آلية حفظ الكائنات المدمجة في بايثون (pickle). تحتوي قاعدة بيانات ZODB على كائن جذر واحد (عادةً ما يكون قاموسًا)، وهو الكائن الوحيد الذي يمكن الوصول إليه مباشرةً من قاعدة البيانات. يتم الوصول إلى جميع الكائنات الأخرى المخزنة في قاعدة البيانات من خلال كائن الجذر. كما يتم تخزين الكائنات التي يشير إليها كائن مخزن في قاعدة البيانات تلقائيًا في قاعدة البيانات أيضًا.

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

مثال

على سبيل المثال، لنفترض أن لدينا سيارة موصوفة باستخدام 3 فئات Car، Wheelو Screw. في لغة بايثون، يمكن تمثيل ذلك بالطريقة التالية:

فئة السيارة : [ ... ] فئة العجلة : [ ... ] فئة البرغي : [ ... ]myCar = Car ( ) myCar.wheel1 = Wheel ( ) myCar.wheel2 = Wheel ( ) for wheel in ( myCar.wheel1 , myCar.wheel2 ) : wheel.scroughs = [ Screw ( ) , Screw ( ) ]

إذا كان المتغير mycar هو أصل الاستمرارية، فإن:

zodb [ 'mycar' ] = myCar

يؤدي هذا إلى تخزين جميع نسخ الكائنات (سيارة، عجلة، براغي، إلخ) في وحدة التخزين، والتي يمكن استرجاعها لاحقًا. إذا اتصل برنامج آخر بقاعدة البيانات عبر كائن mycar، فسيتم تنفيذ ما يلي:

سيارة = zodb [ 'myCar' ]

ويسترجع جميع الكائنات، مع الاحتفاظ بمؤشر السيارة في carالمتغير. ثم في مرحلة لاحقة، يمكن تعديل هذا الكائن باستخدام كود بايثون مثل:

car.wheel3 = Wheel ( ) car.wheel3.scrolls = [ Screw ( ) ]

يتم تعديل التخزين ليعكس تغيير البيانات (بعد إصدار أمر الالتزام).

لا يوجد تعريف لبنية البيانات في كل من بايثون أو ZODB، لذلك يمكن إضافة حقول جديدة بحرية إلى أي كائن موجود.

وحدة تخزين

لكي يتم الحفاظ على البيانات، يجب أن يتم اشتقاق فئة Python Car من Persistence.Persistentالفئة - تحتوي هذه الفئة على البيانات اللازمة لعمل آلية الحفاظ على البيانات، مثل معرف الكائن الداخلي وحالة الكائن وما إلى ذلك، ولكنها تحدد أيضًا حدود الحفاظ على البيانات بالمعنى التالي: كل كائن تشتق فئته من Persistent هو الوحدة الذرية للتخزين (يتم نسخ الكائن بأكمله إلى التخزين عند تعديل حقل).

في المثال أعلاه، إذا Carكانت الفئة الوحيدة المشتقة من Persistent، فعند wheel3إضافة عنصر إلى السيارة، يجب كتابة جميع العناصر في وحدة التخزين. في المقابل، إذا Wheelكانت الفئة مشتقة أيضًا من Persistent، فعند carzz.wheel3 = Wheelتنفيذ عملية الإضافة، يُكتب سجل جديد في وحدة التخزين لحفظ القيمة الجديدة للعنصر ، مع الاحتفاظ Carبالقيم الموجودة ، ويشير السجل الجديد للعنصر إلى السجل الموجود مسبقًا في وحدة التخزين.WheelCarWheel

لا يتتبع نظام ZODB التعديلات عبر شبكة المؤشرات. في المثال أعلاه، carzz.wheel3 = somethingيُعدّ تعديلًا يتم تتبعه تلقائيًا بواسطة نظام ZODB، لأنه carzzمن فئة (Persistent) Car. يقوم نظام ZODB بذلك عن طريق وضع علامة على السجل كـ dirty. مع ذلك، إذا كانت هناك قائمة، فلن يلاحظ نظام ZODB أي تغيير داخلها، ويتعين على المبرمج المساعدة بإضافة يدويًا carzz._p_changed = 1، لإعلام ZODB بأن السجل قد تغير بالفعل. لذا، يجب على المبرمج، إلى حد ما، أن يكون على دراية بآلية عمل نظام التخزين الدائم.

الذرية

وحدة التخزين (أي الكائن الذي تشتق فئته من Persistent) هي أيضًا وحدة الذرية . في المثال أعلاه، إذا Carsكانت الفئة الوحيدة من نوع Persistent هي Wheel، وقام أحد الخيوط بتعديل Wheel ( Carيجب إخطار السجل)، وقام خيط آخر بتعديل Wheel آخر Wheelضمن معاملة أخرى، فسيفشل الالتزام الثاني. أما إذا Wheelكانت الفئة الأخرى من نوع Persistent أيضًا، فيمكن تعديل كليهما Wheelsبشكل مستقل بواسطة خيطين مختلفين في معاملتين مختلفتين.

استمرارية الفئة

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

زيو

Zope Enterprise Objects (ZEO) هو تطبيق تخزين ZODB يسمح لعمليات العميل المتعددة بتخزين الكائنات على خادم ZEO واحد. وهذا يسهل التوسع الشفاف.

وحدات تخزين قابلة للتوصيل

تُمكّن خاصية التخزين الشبكي (المعروفة أيضًا باسم ZEO) عمليات بايثون متعددة من تحميل وتخزين البيانات الدائمة في وقت واحد. بينما تسمح خاصية تخزين الملفات لعملية بايثون واحدة بالتفاعل مع ملف على القرص. أما خاصية RelStorage فتُمكّن نظام إدارة قواعد البيانات العلائقية (RDBMS) من أن يكون مخزن البيانات الدائمة . ويقوم نظام تخزين الدليل بتخزين كل بيانات دائمة كملف منفصل على نظام الملفات، على غرار FSFS في Subversion . ويُستخدم نظام Demo Storage كخلفية في الذاكرة لمخزن البيانات الدائمة. أما BDBStorage، الذي تم التخلي عنه الآن، فكان يستخدم قاعدة بيانات Berkeley DB كخلفية.

تقنيات تجاوز الأعطال

خدمات النسخ المتماثل لـ Zope (ZRS) هي إضافة تجارية للتعافي من الأعطال ، مفتوحة المصدر منذ مايو 2013، تقضي على نقطة الفشل الوحيدة ، وتوفر نسخًا احتياطيًا فوريًا للكتابة وموازنة الأحمال للقراءة. أما ZeoRAID فهو حل مفتوح المصدر يوفر خادم شبكة وسيطًا يوزع مخازن الكائنات والاستعادة عبر سلسلة من خوادم الشبكة. بينما يُغني RelStorage، باستخدام تقنيات إدارة قواعد البيانات العلائقية، عن الحاجة إلى خادم ZEO. أما NEO فهو تطبيق تخزين موزع يوفر تحمل الأعطال وموازنة الأحمال.

مراجع