اذهب إلى المحتوى

لوحة المتصدرين

  1. عبدالرحيم فاخوري

    • نقاط

      1

    • المساهمات

      22


  2. kinan mawed

    kinan mawed

    الأعضاء


    • نقاط

      1

    • المساهمات

      45


المحتوى الأكثر حصولًا على سمعة جيدة

عرض المحتوى الحاصل على سمعة أكبر منذ 11/03/25 in مقالات DevOps

  1. منذ زمن سحيق، كانت الذاكرةُ أكثر وظيفة نحتاجها ونعتمد عليها في الحاسوب. ورغم اختلاف التقنيات وأساليب التنفيذ الكامنة وراءها، إلّا أنّ معظم الحواسيب تأتي بالعتاد الضروريّ لمعالجة المعلومات وحفظها بأمان لاستخدامها في المستقبل متى احتجنا لها. لقد صار من المستحيل في عالمنا الحديث تخيل أيّ عمل لا يستفيد من هذه القدرة في الأجهزة، سواء كانت خواديم أو حواسيب شخصية أو كفّيّة. تُعالَج البيانات وتُسجَّل وتُسترجَع مع كل عملية، وفي كل مكان من الألعاب إلى الأدوات المتعلقة بالأعمال، بما فيها المواقع. أنظمة إدارة قواعد البيانات (DataBase Management Systems – DBMS) هي برمجيات عالية المستوى تعمل مع واجهات برمجة تطبيقات (APIs) أدنى منها في المستوى، وتلك الواجهات بدورها تهتم بهذه العمليات. لقد تم تطوير العديد من أنظمة إدارة قواعد البيانات (كقواعد البيانات العلائقيّة relational databases، وnoSQL، وغيرها) لعقود من الزمن للمساعدة على حلّ المشكلات المختلفة، إضافة إلى برامج لها (مثل MySQL ,PostgreSQL ,MongoDB ,Redis، إلخ). سنقوم في هذا المقال بالمرور على أساسيّات قواعد البيانات وأنظمة إدارة قواعد البيانات. وسنتعرف من خلالها على المنطق الذي تعمل به قواعد البيانات المختلفة، وكيفية التفرقة بينها. أنظمة إدارة قواعد البياناتإن مفهوم نظام إدارة قاعدة البيانات مظلّةٌ تندرج تحتها كلّ الأدوات المختلفة أنواعها (كبرامج الحاسوب والمكتبات المضمّنة)، والتي غالبًا تعمل بطرق مختلفة وفريدة جدًّا. تتعامل هذه التطبيقات مع مجموعات من المعلومات، أو تساعد بكثرة في التعامل معها. وحيث أن المعلومات (أو البيانات) يُمكِن إن تأتي بأشكال وأحجام مختلفة، فقد تم تطوير العشرات من أنظمة قواعد البيانات، ومعها أعداد هائلة من تطبيقات قواعد البيانات منذ بداية النصف الثاني من القرن الحادي والعشرين، وذلك من أجل تلبية الاحتياجات الحوسبيّة والبرمجية المختلفة. تُبنى أنظمة إدارة قواعد البيانات على نماذج لقواعد البيانات: وهي بُنى محدّدة للتعامل مع البيانات. وكل تطبيق ونظام إدارة محتوى جديد أنشئ لتطبيق أساليبها يعمل بطريقة مختلفة فيما يتعلق بالتعريفات وعمليات التخزين والاسترجاع للمعلومات المُعطاة. ورغم أنّ هناك عددًا كبيرًا من الحلول التي تُنشئ أنظمة إدارة قواعد بيانات مختلفة، إلّا أنّ كلّ مدة زمنية تضمّنت خيارات محدودة صارت شائعة جدًّا وبقيت قيد الاستخدام لمدة أطول، والغالب أنّ أكثرها هيمنة على هذه الساحة خلال العقدين الأخيرين (وربما أكثر من ذلك) هي أنظمة إدارة قواعد البيانات العلائقيّة (Relational Database Management Systems – RDBMS). أنواع قواعد البياناتيستخدم كلُّ نظام إدارة بياناتٍ نموذجًا لقواعد البيانات لترتيب البيانات التي يديرها منطقيًّا. هذه النماذج (أو الأنواع) هي الخطوة الأولى والمحدّد الأهم لكيفية عمل تطبيق قواعد البيانات وكيفية تعامله مع المعلومات وتصرفه بها. هناك بعض الأنواع المختلفة لنماذج لقواعد البيانات التي تعرض بوضوع ودقّة معنى هيكلة البيانات، والغالب أن أكثر هذه الأنواع شهرةً قواعدُ البيانات العلائقيّة. ورغم أنّ النموذج العلائقيّ وقواعد البيانات العلائقيّة (relational databases) مرنة وقويّة للغاية –عندما يعلم المبرمج كيف يستخدمها–، إلّا أنّ هناك بعض المشكلات التي واجهات عديدين، وبعض المزايا التي لم تقدمها هذه الحلول. لقد بدأت حديثًا مجموعة من التطبيقات والأنظمة المختلفة المدعوّة بقواعد بيانات NoSQL بالاشتهار بسرعة كبيرة، والتي قدمت وعودًا لحل هذه المشكلات وتقديم بعض الوظائف المثيرة للاهتمام بشدّة. بالتخلص من البيانات المهيكلة بطريقة متصلّبة (بإبقاء النمط المعرّف في النموذج العلائقيّ (relational model))، تعمل هذه الأنظمة بتقديم طريقة حرّة أكثر في التعامل مع المعلومات، وبهذا توفّر سهولة ومرونة عاليتين جدًّا؛ رغم أنّها تأتي بمشاكل خاصة بها –والتي تكون بعضها جدّيّة– فيما يتعلق بطبيعة البيانات الهامّة والتي لا غنى عنها. النموذج العلائقيّيقدّم النظام العلائقيّ الذي ظهر في تسعينات القرن الماضي طريقة مناسبة للرياضيات في هيكلة وحفظ واستخدام البيانات. توسّع هذه الطريقة من التصاميم القديمة، كالنموذج المسطّح (flat)، والشبكيّ، وغيرها، وذلك بتقديمها مفهوم "العلاقات". تقدّم العلاقات فوائد تتعلق بتجميع البيانات كمجموعات مقيّدة، تربط فيها جداول البيانات –المحتوية على معلومات بطريقة منظمة (كاسم شخص وعنوانه مثلاً)– كل المدخلات بإعطاء قيم للصفات (كرقم هوية الشخص مثلًا). وبفضل عقود من البحث والتطوير، تعمل أنظمة قواعد البيانات التي تستخدم النموذج العلائقيّ بكفاءة وموثوقيّة عاليتين جدًّا. أضف إلى ذلك الخبرة الطويلة للمبرمجين ومديري قواعد البيانات في التعامل مع هذه الأدوات؛ لقد أدّى هذا إلى أن يصبح استخدام تطبيقات قواعد البيانات العلائقيّة الخيار الأمثل للتطبيقات ذات المهام الحرجة، والتي لا يمكنها احتمال فقدان أيّة بيانات تحت أيّ ظرف، وخاصة كنتيجة لخلل ما أو لطبيعة التطبيق نفسه الذي قد يكون أكثر عرضة للأخطاء. ورغم طبيعتها الصارمة المتعلقة بتشكيل والتعامل مع البيانات، يمكن لقواعد البيانات العلائقيّة أن تكون مرنة للغاية وأن تقدم الكثير، وذلك بتقديم قدر ضئيل من المجهود. التوجّه عديم النموذج (Model-less) أو NoSQLتعتمد طريقة NoSQL في هيكلة البيانات على التخلص من هذه القيود، حيث تحرر أساليب حفظ، واستعلام، واستخدام المعلومات. تسعى قواعد بيانات NoSQL إلى التخلص من العلائقات المعقدة، وتقدم أنواع عديدة من الطرق للحفاظ على البيانات والعمل عليها لحالات استخدام معينة بكفاءة (كتخزين مستندات كاملة النصوص)، وذلك من خلال استخدامها توجّها غير منظم (أو الهيكلة على الطريق / أثناء العمل). أنظمة إدارة قواعد بيانات شائعةهدفنا في هذا المقال هو أن نقدم لك نماذج عن بعض أشهر حلول قواعد البيانات وأكثرها استخدامًا. ورغم صعوبة الوصول إلى نتيجة بخصوص نسبة الاستخدام، يمكننا بوضوح افتراض أنّه بالنسبة لغالب الناس، تقع الاختيارات بين محرّكات قواعد البيانات العلائقيّة، أو محرك NoSQL أحدث. لكن قبل البدء بشرح الفروقات بين التطبيقات المختلفة لكل منهما، دعنا نرى ما يجري خلف الستار. أنظمة إدارة قواعد البيانات العلائقيّةلقد حصلت أنظمة إدارة قواعد البيانات العلائقيّة على اسمها من النموذج الذي تعتمد عليه، وهو النموذج العلائقيّ الذي ناقشناه أعلاه. إنّ هذه الأنظمة –الآن، وستبقى لمدة من الزمن في المستقبل– الخيار المفضّل للحفاظ على البيانات موثوقة وآمنة؛ وهي كذلك كفؤة. تتطلب أنظمة إدارة قواعد البيانات العلائقيّة مخططات معرفة ومحددة جيدًا –ولا يجب أن يختلط الأمر مع تعريف PostgreSQL الخاص بهذه الأنظمة– لقبول هذه البيانات. تشكّل هذه الهيئات التي يحددها المستخدم كيفية حفظ واستخدام البيانات. إنّ هذه المخططات شبيهة جدًّا بالجداول، وفيها أعمدة تمثّل عدد ونوع المعلومات التي تنتمي لكل سجل، والصفوف التي تمثّل المدخلات. من أنظمة إدارة قواعد البيانات الشائعة نذكر: SQLite: نظام إدارة قواعد بيانات علائقيّة مضمّن قويّ جدًّا.MySQL: نظام إدارة قواعد بيانات علائقيّة الأكثر شهرة والشائع استخدامه.PostgreSQL: أكثر نظام إدارة قواعد بيانات علائقيّة كيانيّ (objective-RDBMS) متقدم وهو متوافق مع SQL ومفتوح المصدر.ملاحظة: لمعرفة المزيد عن أنظمة إدارة قواعد بيانات NoSQL، راجع المقالة التالية عن الموضوع: A Comparison Of NoSQL Database Management Systems. أنظمة قواعد بيانات NoSQL (أو NewSQL)لا تأتي أنظمة قواعد بيانات NoSQL بنموذج كالمستخدم في (أو الذي تحتاجه) الحلول العلائقيّة المهيكلة. هناك العديد من التطبيقات، وكلّ منها تعمل بطريقة مختلفة كليًّا، وتخدم احتياجات محدّدة. هذه الحلول عديمة المخططات (schema-less) إمّا تسمح تشكيلات غير محدودة للمدخلات، أو –على العكس– بسيطة جدًّا ولكنها كفؤة للغاية كمخازن قيم معتمد على المفاتيح (key based value stores) مفيدة. على خلاف قواعد البيانات العلائقيّة التقليديّة، يمكن تجميع مجموعات من البينات معًا باستخدام قواعد بيانات NoSQL، كـ MongoDB مثلًا. تُبقي مخازن المستندات هذه كل قطعة من البيانات مع بعضها كمجموعة واحدة (أي كملف) في قاعدة البيانات. يمكن تمثيل هذه المستندات ككيانات بيانات منفردة، مثلها في ذلك كمثل JSON، ومع ذلك تبقى كراسات، وذلك يعتمد على خصائصها. ليس لقواعد بيانات NoSQL طريقة موحدة للاستعلام عن البيانات (مثل SQL لقواعد البيانات العلائقيّة) ويقدم كلّ من الحلول طريقته الخاصّة للاستعلام. ملاحظة: لمعرفة المزيد عن أنظمة إدارة قواعد البيانات العلائقيّة، ألق نظرة على هذه المقالة المتعلقة بالموضوع: A Comparison Of Relational Database Management Systems. مقارنة بين أنظمة إدارة قواعد بيانات SQL و NoSQLمن أجل الوصول إلى نتيجة بسيطة ومفهومة، لنحلّل أولًا الاختلافات بين أنظمة إدارة قواعد البيانات: هيكلية ونوع البيانات المحتفظ بها:تتطلب قواعد البيانات العلائقيّة SQL هيكلة ذات خصائص محدّدة للحفاظ على البيانات، على خلاف قواعد بيانات NoSQL التي تسمح بعمليات انسياب حُرّ (free-flow operations). الاستعلام: وبغضّ النظر عن تراخيصها، تستخدم كلّ قواعد البيانات العلائقيّة معيار SQL إلى حدّ ما، ولهذا يمكن الاستعلام فيها بلغة SQL (أي Structured Query Language). أما قواعد بيانات NoSQL فلا تستخدم طريقة محدّدة للعمل على البيانات التي تديرها. التحجيم: يمكن تحجيم كلي الحلين عموديًّا (أي بزيادة موارد النظام). لكن لكون حلول NoSQL تطبيقات أحدث (وأبسط)، فهذا يجعلها تقدّم وسائل أسهل بكثير لتحجيمها أفقيًّا (أي بإنشاء شبكة عنقودية cluster من أجهزة متعدّدة). المتانة Reliability: عندما يتعلق الأمر بالمتانة والثقة الآمنة بالقَيد المنفّذ، تبقى قواعد بيانات SQL الخيار الأفضل. الدعم: لأنظمة إدارة قواعد البيانات العلائقيّة تاريخ طويل استمر لعقود من الزمن. إنها شائعة جدًّا، ومن السهل إيجاد دعم سواء مجانيّ أو مدفوع. إذا حدثت مشكلة، فمن الأسهل حلّها عليها من قواعد بيانات NoSQL التي شاعت حديثًا، وخاصة إذا كان الحلّ موضع السؤال ذا طبيعة معقّدة (مثل MongoDB). احتياجات حفظ واستعلام البيانات المعقدة: إنّ قواعد البيانات العلائقيّة بطبيعتها الخيار الأمثل لاحتياجات حفظ البيانات والاستعلامات المعقّدة. إنها أكثر كفاءة وتتفوق في هذا المجال. ترجمة -وبتصرّف- للمقال Understanding SQL And NoSQL Databases And Different Database Models لصاحبه O.S. Tezer.
    1 نقطة
  2. Sqlite هي عبارة عن محرك SQL مفتوح المصدر سريع وبسيط جدا، يشرح هذا الدرس متى يكون من الأمثل استخدام Sqlite كبديل لأنظمة إدارة قواعد البيانات الارتباطية RDBMS مثل MySQL أو Postgres، بالإضافة إلى كيفية تثبيتها وأمثلة عن استخداماتها الأساسية، تُغطي عمليات CRUD: الإنشاء Create، القراءة Read، التحديث Update، والحذف Delete. مفاهيم خاطئةلا يجب أن ننخدع بالاعتقاد أن Sqlite تستَخدم فقط للاختبار والتطوير، فعلى سبيل المثال تعمل Sqlite بشكل جيد لمواقع الإنترنت التي تتلقى 100,000 زائر يوميا، وهذا هو الحد المُحافظ. إن الحد الأقصى لحجم قاعدة بيانات Sqlite هو 140 تيرابايت (والذي من المفترض أن يكون كافيًا، أليس كذلك؟)، وبإمكانها أن تكون أسرع بكثير من RDBMS، يتم تخزين قاعدة البيانات كاملةمع كافة البيانات الضرورية في ملف عادي في نظام ملفات المضيف Host، ولذلك لا توجد حاجة لعملية خادوم Server منفصلة (الاستغناء عن الحاجة إلى الاتصالات البطيئة بين العمليّات). الاستخدام الأمثل على VPS الخاص بناتركز Sqlite على البساطة، وبما أنها تعمل داخليا internal بشكلٍ تام، فهي غالبًا ما تكون أسرع بكثير من البدائل الأخرى، إن كنا نبحث عن قابلية النقل portability (فيما يتعلق باللغات والمنصّات معًا)، البساطة، السرعة، والاستهلاك القليل للذاكرة فإن Sqlite مثاليّة لهذا، فعيوبها تكون واضحة فقط عند الحاجة لتزامن عال بالقراءة أو الكتابة. حيث تستطيع Sqlite أن تدعم كاتب writer واحد فقط في نفس الوقت، وقد يكون زمن الوصول latency لنظام الملفات المرتَفِع عادة غير مُلائِم إن كانت هناك حاجة لنفاذ access العديد من العملاء إلى قاعدة بيانات Sqlite في نفس الوقت. العيب الأخير المُحتَمل وجوده في Sqlite هو صياغتها syntax الفريدة، بالرغم من تشابهها مع أنظمة SQL الأخرى، ومن البديهي عند الانتقال إلى نظام آخر -إن قمنا باستخدام Sqlite والتي تتطوّر بسرعة- أن نجد بعض العقبات في المرحلة الانتقاليّة. تثبيت Sqlite على VPS الخاص بناإن وحدة sqlite3 module هي جزء من مكتبة بايثون المعيارية، لذلك لا نحتاج لأي تثبيت آخر على توزيعة Ubuntu المعيارية أو على أي نظام آخر مُثبّت عليه بايثون، ولتثبيت واجهة سطر الأوامر لـ Sqlite على Ubuntu نستخدم هذه الأوامر: sudo apt-get update sudo apt-get install sqlite3 libsqlite3-devإن كُنّا نريد تصريفه Compile من المصدر Source يجب علينا الحصول على آخر إصدار من autoconf من الرّابط sqlite.org/download.html، وهو الإصدار المتوفّر وقت كتابة هذا الدّرس: wget http://sqlite.org/2013/sqlite-autoconf-3080100.tar.gz tar xvfz sqlite-autoconf-3080100.tar.gz cd sqlite-autoconf-3080100 ./configure make make installملاحظات من أجل البناء من المصدر: لا يجب أن نقوم بفعل هذا على توزيعة Ubuntu معياريّة لأنّه من المُحتمل أن نتلقّى خطأ عن عدم التّوافق في إصدار التّرويسة Header والمصدر "header and source version mismatch" بسبب التّعارض بين الإصدار المُثبّت حاليًّا والإصدار الجّديد الذي نريد تثبيته.إن كان يبدو أنّ الأمر make ينتظر المزيد من المُدخلات منك فكُن صبورًا فقط، حيث أنّ تصريف Compile المصدر قد يستغرق بعض الوقت.الاستخدامات الأساسية لواجهة سطر الأوامرلإنشاء قاعدة بيانات نقوم بتنفيذ الأمر التالي: sqlite3 database.dbحيث يكون database هو اسم قاعدة البيانات لدينا، وإن كان الملف database.db موجودًا مُسبقًا ستقوم Sqlite بإنشاء اتصال معه، وإن لم يكن موجودًا سيتمّ إنشاؤه، يجب أن يكون الخرج Output مُشابهًا لما يلي: SQLite version 3.8.1 2013-10-17 12:57:35 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>فلنقم الآن بإنشاء جدول Table وإدخال بعض البيانات إليه، يملك هذا الجدول المُسمَّى الأندية clubs أربعة أعمدة columns، من أجل id، اسم النادي name، مدرّبه coach، وبلد النّادي country، سنقوم بإدخال بيانات ثلاثة أندية كرة قدم إلى قاعدة بياناتنا: CREATE TABLE clubs (id integer, name varchar(30), coach varchar(20), country varchar(20)); INSERT INTO clubs VALUES (1, "Real Madrid", "Benitez", "Spain"); INSERT INTO clubs VALUES (2, "Barcelona", "Enrique", "Spain"); INSERT INTO clubs VALUES (3, "Chelsea", "Mourinho", "England");لقد أنشأنا قاعدة بيانات، جدول، وبعض الإدخالات، نضغط الآن Ctrl+D للخروج من Sqlite ونكتب ما يلي (يجب هنا أيضًا أن نضع اسم قاعدة بياناتنا بدلًا من 'database') والذي سيقوم بإعادة الاتصال إلى قاعدة البيانات التي أنشأناها للتو: sqlite3 database.dbالآن نكتب: SELECT * FROM clubs;يجب أن نرى هنا الإدخالات التي قُمنا بها: 1|Real Madrid|Benitez|Spain 2|Barcelona|Enrique|Spain 3|Chelsea|Mourinho|Englandرائع، هذا هو كلّ شيء فيما يتعلّق بالإنشاء Creating والقراءة Reading، فلنقم الآن بالتّحديث Update والحذف Delete: UPDATE clubs SET country="Spain" WHERE country="England";سيقوم هذا الأمر بتحديث قاعدة البيانات بحيث يجعل الأندية المُدرَجة على أنّها من إنكلترا يتم إدراجها وكأنّها أندية من إسبانيا، فلنتأكّد من النتائج باستخدام الأمر: SELECT * FROM clubs;يجب أن نرى: 1|Real Madrid|Benitez|Spain 2|Barcelona|Enrique|Spain 3|Chelsea|Mourinho|Spainأصبحت لدينا الآن كل الأندية من إسبانيا، فلنقم بحذف Chelsea من قاعدة بياناتنا كونه النادي الوحيد الذي في الحقيقة ليس من إسبانيا: DELETE FROM clubs WHERE id=3; SELECT * FROM clubs;ينبغي أن نجد الآن عدد الأندية لدينا أقل بواحد من السّابق: 1|Real Madrid|Benitez|Spain 2|Barcelona|Enrique|Spainيُغطِّي هذا جميع العمليّات الأساسيّة لقواعد البيانات، وقبل أن ننتهي دعونا نجرّب مثالًا آخر أقل بديهيّة بقليل، والذي يستخدم جدولين وانضمام join أساسي بينهما. فلنخرج الآن من Sqlite باستخدام الأمر Ctrl+D ونعيد الاتصال إلى قاعدة بيانات جديدة باستخدام: sqlite3 database2.dbسنقوم بإنشاء جدول مشابه جدًّا لجدول الأندية clubs ولكنّنا سننشئ أيضًا جدول للدول countries، والذي يقوم بتخزين اسم الدّولة ورئيسها الحالي، فلنقم أولًا بإنشاء جدول الدّول countries وإدخال إسبانيا وفرنسا إليه باستخدام ما يلي (لاحظ أنّنا نستطيع نسخ ولصق عدّة أسطر من شيفرة sqlite دفعة واحدة): CREATE TABLE countries (id integer, name varchar(30), president varchar(30)); INSERT INTO countries VALUES (1, "Spain", "Rajoy Brey"); INSERT INTO countries VALUES(2, "France", "Francois Hollande");ونستطيع بعدها إعادة إنشاء الجدول clubs باستخدام ما يلي: CREATE TABLE clubs (id integer, name varchar(30), country_id integer); INSERT INTO clubs VALUES (1, "Real Madrid", 1); INSERT INTO clubs VALUES (2, "Barcelona", 1); INSERT INTO clubs VALUES (3, "Chelsea", 2);دعونا الآن نرى ما هي الأندية الموجودة في إسبانيا باستخدام: SELECT name FROM clubs JOIN countries ON country_id=countries.id WHERE countries.name="Spain";ينبغي أن نشاهد ما يلي: Real Madrid Barcelonaيُغطّي هذا موضوع الانضمام الأساسي basic join، فلنلاحظ أنّ sqlite تفعل الكثير من أجلنا، ففي التّعبير السّابق يرمز الانضمام Join افتراضيًّا إلى INNER JOIN بالرغم من أنّنا استخدمنا فقط الكلمة المفتاحيّة JOIN، ولا يجب علينا أيضًا تحديد clubs.country_id لأنّها واضحة لا لبس فيها، من ناحية أخرى إن جرّبنا هذا الأمر: SELECT name FROM clubs JOIN countries ON country_id=id WHERE country_id=1;سنتلقّى رسالة خطأ: "Error: ambiguous column name: id" وهو خطأ معقول بما فيه الكفاية لأنّ الجدولين لدينا كلاهما يملكان عمود id، ولكن بشكلٍ عام sqlite متسامحة مع الأخطاء إلى حد ما، فرسائل الأخطاء فيها تميل إلى أن تجعل تحديد مكان أيّ مشاكل وإصلاحها شيئًا بديهيا إلى حد ما، وهذا يُساعد على تسريع عمليّة التّطوير. للمزيد من المساعدة في موضوع الصّياغة Syntax فإنّ الوثائق الرّسميّة لها مليئة بالمخطّطات البيانيّة diagrams مثل هذا sqlite.org/langdelete.html، والتي من الممكن أن تكون مفيدة. وفي الختام، تملك sqlite أغلفة wrappers وتعريفات في جميع اللغات الرئيسيّة، ويُمكن تشغيلها على معظم الأنظمة، نستطيع إيجاد قائمة بالعديد من هذه اللغات هنا، حظًّا سعيدًا واستمتع بوقتك. ترجمة -وبتصرّف- للمقال How and When to Use Sqlite لصاحبه Gareth Dwyer.
    1 نقطة
×
×
  • أضف...