1. بسم الله الرحمن الرحيم
    مقدمة:
    المقصود ب (Subquery) استعلام داخل استعلام. ويسمى أيضا استعلام داخلي (Inner query) أو استعلام متداخل (Nested query)
    A Subquery or Inner query or a Nested query is a query within another SQL query and embedded within the WHERE clause (1).
    مثال:
    SELECT * FROM Students WHERE CollegeID IN (SELECT CollegeID FROM Universities WHERE Location = 'Saudi Arabia') حتى نعرف الفرق بين (Simple subquery) و (Correlated subquery) نحتاج أن نعرف معنى (Inner query and Outer query).
    في المثال السابق الجزء:
    SELECT * FROM Students WHERE CollegeID IN يسمى الاستعلام الخارجي (Outer query)
    والجزء
    (SELECT CollegeID FROM Universities WHERE Location = 'Saudi Arabia') يسمى الاستعلام الداخلي (Inner query)
     
    الفرق بين Simple subquery and Correlated subquery
    حتى يتضح الفرق لنفرض أن لدينا جدول خاص بالعملاء ( الرقم – الاسم – العمر – الدولة) وأيضا جدول للدول (الرقم – اسم الدولة) كما في الصورة


     
    الاستعلام الفرعي البسيط (Simple subquery)
    يكون فيه الاستعلام الداخلي (Inner query) غير معتمد على الاستعلام الخارجي (Outer query) بمعنى أن يكون الاستعلام الداخلي مستقل ويمكن تنفيذه بشكل مستقل.
     
    مثال: استعلام يعرض لنا كامل بيانات العملاء من دولة المملكة العربية السعودية.
    SELECT * FROM Customers WHERE CountryID IN (SELECT CountryID FROM Countries WHERE CountryName ='KSA') ويكون الناتج:

     
    توضيح آلية تنفيذ الـ Simple subquery:
    في البداية يتم تنفيذ الاستعلام الداخلي (Inner query)  مرة واحدة فقط. حيث يتم الحصول على رقم دولة (السعودية KSA ). ثم يتم تمرير الناتج للاستعلام الخارجي (Outer query) ويتم الاستفادة منه في الشرط. بمعنى لا يتم تكرار تنفيذ الاستعلام الداخلي.
     
    الاستعلام الفرعي المترابط (Correlated subquery)
    يكون فيه الاستعلام الداخلي (Inner query) معتمد على الاستعلام الخارجي (Outer query) أي أنه يوجد في الاستعلام الداخلي جزء يعتمد على الاستعلام الخارجي.
     
    مثال: استعلام يعرض كامل بيانات الدول المرتبط بها عملاء
    SELECT * FROM Countries cnt WHERE cnt.CountryID IN (SELECT cus.CountryID From Customers cus WHERE cus.CountryID = cnt.CountryID) ويكون الناتج:

    هنا نلاحظ في الجزئية الأخيرة (WHERE cus.CountryID = cnt.CountryID) الموجودة في الاستعلام الداخلي
    أن الحقل (CountryID) في جدول الدول (Countries) موجود في الاستعلام الخارجي وهنا تم الاعتماد عليه في الاستعلام الداخلي.
    توضيح آلية تنفيذ الـ Correlated subquery:
    هنا الموضوع يختلف عن الـ Simple subquery حيث يتم أولا تنفيذ الاستعلام الخارجي حيث يبدأ بالسجل الأول من جدول الدول وهو السعودية ثم يتم تمرير رقم الدولة (1) إلى الاستعلام الداخلي ويتم مطابقة الرقم (1) القادم من الاستعلام الخارجي مع رقم الدولة الموجود في جدول العملاء والموجود في الاستعلام الداخلي (WHERE cus.CountryID = cnt.CountryID) للتأكد من هل العميل مرتبط بهذه الدولة فإذا لم يكون مرتبط ينتقل للسجل الثاني في جدول العملاء ( نحن الآن في السجل الآول من جدول الدول والسجل الثاني من جدول العملاء) وهكذا حتى يتأكد من كامل العملاء.
    ثم يتنقل للسجل الثاني من جدول الدول وهو دولة الإمارات رقم (2) ثم يمرره إلى الاستعلام الداخلي ويتم البحث في جدول العملاء ويبدأ المقارنة بنفس الطريقة.
    بمعنى أن إذا كان لدينا 3 سجلات في جدول الدول ولدينا 4 سجلات في جدول العملاء في كل سجل من جدول الدول يتم المرور على 4 سجلات من جدول العملاء وهذا يشكل حلقة (loop).
     
    الخلاصة:
    الفرق بين الاستعلام الفرعي البسيط (Simple subquery) والاستعلام الفرعي المترابط (Correlated subquery) يكون في النقاط التالية:
    الاستعلام الداخلي في Simple subquery لا يعتمد على الاستعلام الخارجي ويتم تنفيذه بشكل مستقل. أما في Correlated subquery الاستعلام الداخلي يعتمد على الاستعلام الخارجي. في الـ Simple subquery يتم أولاً تنفيذ الاستعلام الداخلي مرة واحدة فقط ولا يشكل حلقة (loop). أما في Correlated subquery يتم تنفيذ الاستعلام الخارجي أولاً ومع كل سجل من الاستعلام الخارجي يتم تنفيذ الاستعلام الداخلي وذلك يشكل حلقة (Loop). الـ Simple subquery أسرع من حيث الأداء بناء على النقطة الثانية.(2)  
    (1): https://www.tutorialspoint.com/sql/sql-sub-queries.htm
    (2): http://stackoverflow.com/a/21036822
     
    تمت بحمد الله.
    Talal Almutairi
    https://twitter.com/talalsql
    مستوى المقال: مبتدئ
  2. السلام عليكم ورحمة الله وبركاته ..
    من بعد المقدمة حول قاعدة بيانات الـMongoDB حيث تم التعرف على:
    ما نوع قاعدة البيانات. كيفية تخزين البيانات فيها. العمليات البسيطة منها الـfind. الفروقات السطيحة مابين الـMongoDB و قواعد البيانات الأخرى من نوع RDBMS. لماذا انصح بالتحول إلى هذا النوع من قواعد البيانات.  
    إذا , اصبح هناك نظرة شاملة حول هذا النوع من قواعد البيانات و في هذا الدرس سنبدأ بأول العمليات المهمة والاساسية التي تسمى بـCRUD اختصارا إلى:
    Create Read Update Delete  
    نبدأ بسمه تعالى, افتح الـCMD او الـTerminal و اكتب الكوماند التالي لتفعيل خدمة الـMongoDB في جهازك
     
    بعد ذلك افتح CMD آخر واكتب الكوماند التالي للدخول على MongoDB Shell
    بعد الدخول على الـMongoDB Shell لمعلومات اكثر اكتب help  
    لندا بتصفح قواعد البيانات الموجوده مسبقا في بكتابه show dbs ستظهر قاعدة بيانات واحده اسمها local تحتوي على collection بإسم startup_log وهنا ننوه مره اخرى بأن:
    اسم الـTable في الـMongoDB هو Collection
    اسم الـRow في الـMongoDB هو Document
     
    قم بإنشاء قاعدة بيانات جديدة و اختارها من خلال كوماند واحد
     
    و DATABASE_NAME تعني اسم قاعدة البيانات التي تريد عملها ولنفترض abdullashop
     
    بعد انشاء قاعدة البيانات واختيارها نبدأ الآن بعمل collection بإسم مثلا customers
    db.createCollection("customers") //results /* { "ok" : 1 } */  
    أولا: Create
     
    الأن نأتي لموضوع الإضافه بداخل الكولكشن .. للإضافه هناك ثلاث خيارات ممكن استخدامها:
    db.collection.insert() - old db.collection.insertOne() New in version 3.2 db.collection.insertMany() New in version 3.2
     
    و في هذا الدرس سنستخدم insertMany لإضافة اكثر من document في collection بإستخدام كوماند واحد
    Syntax
    db.collection.insertMany( { [ <document 1> , <document 2>, ... ] }, { writeConcern: <document>, ordered: <boolean> } )  
    ماسنضيفه بداخل الكولكشن هو ( اعمل نسخ ومن ثم لصق في الـCMD)
    db.customers.insertMany([ { cus_name: "Abdulla Jassim", payment: 10, branch: "Hamad Town" }, { cus_name: "Mohammed Yousif", payment: 12, branch: "Saar" }, { cus_name: "Yassir Khalaf", payment: 4.5, branch: "Isa Town" }, { cus_name: "omar khalid", payment: 7.2, branch: "Manama" }, { cus_name: "Reem Ali", payment: 34, branch: "Riffa" }, { cus_name: "Fatima Talal", payment: 9.6, branch: "Manama" } ]) // results // /* { "acknowledged" : true, "insertedIds" : [ ObjectId("5803b8ccf9f236bb5591f181"), ObjectId("5803b8ccf9f236bb5591f182"), ObjectId("5803b8ccf9f236bb5591f183"), ObjectId("5803b8ccf9f236bb5591f184"), ObjectId("5803b8ccf9f236bb5591f185"), ObjectId("5803b8ccf9f236bb5591f186") ] } */  
    ثانيا: Read
    بعد عمل قاعدة البيانات , كولكشن و إضافه دوكيومنتس تأتي العمليه الثانية في الـCRUD وهي Read او Find في مصطلحات الـMongoDB وللبحث \ لقراءة جميع المدخلات التي في جدول customers تكون بالكماند التالي ( ملاحظة pretty() function فقط لعرض الناتج بشكل اوضح )
    Syntax
    db.collection.find() db.cunstomers.find({}).pretty() // results // /* { "_id" : ObjectId("5803b8ccf9f236bb5591f181"), "cus_name" : "Abdulla Jassim", "payment" : 10, "branch" : "Hamad Town" } { "_id" : ObjectId("5803b8ccf9f236bb5591f182"), "cus_name" : "Mohammed Yousif", "payment" : 12, "branch" : "Saar" } { "_id" : ObjectId("5803b8ccf9f236bb5591f183"), "cus_name" : "Yassir Khalaf", "payment" : 4.5, "branch" : "Isa Town" } { "_id" : ObjectId("5803b8ccf9f236bb5591f184"), "cus_name" : "omar khalid", "payment" : 7.2, "branch" : "Manama" } { "_id" : ObjectId("5803b8ccf9f236bb5591f185"), "cus_name" : "Reem Ali", "payment" : 34, "branch" : "Riffa" } { "_id" : ObjectId("5803b8ccf9f236bb5591f186"), "cus_name" : "Fatima Talal", "payment" : 9.6, "branch" : "Manama" } */  
    تطبيقات حول db.collection.find
    استخرج اسماء جميع الأشخاص الذين دفعوا اكثر من 10 دنانير .. سيكون الكوماند db.customers.find( { payment:{$gt: 10} }, { payment: 0, branch: 0 , _id: 0 } ) /* { payment:{$gt: 10} } = the condition where payment $gt greater than 10 { payment: 0, branch: 0 , _id: 0 } = exclude these fields/cols from results Resutls: { "cus_name" : "Mohammed Yousif" } { "cus_name" : "Reem Ali" } */  
    استخرج جميع من يحتوي اسمه على المقطع al db.customers.find({cus_name: /al/}).pretty() // Results // /* { "_id" : ObjectId("5803b8ccf9f236bb5591f183"), "cus_name" : "Yassir Khalaf", "payment" : 4.5, "branch" : "Isa Town" } { "_id" : ObjectId("5803b8ccf9f236bb5591f184"), "cus_name" : "omar khalid", "payment" : 7.2, "branch" : "Manama" } { "_id" : ObjectId("5803b8ccf9f236bb5591f186"), "cus_name" : "Fatima Talal", "payment" : 9.6, "branch" : "Manama" } */  
    ثالثا: Update
    لتحديث دوكيومنت معين او عدد من الدوكيومنتس يعتمد على الحاله التي تواجهها:
    db.collection.update() - old db.collection.updateOne() New in version 3.2 db.collection.updateMany() New in version 3.2 db.collection.replaceOne() New in version 3.2  
    ولكن لنبدأ بابسط الاوامر
    Syntax
    db.collection.updateOne(filter, update, options)  
    وأمثلة على ذلك , تحديث مدفوعات من اسمه Abdulla إلى 14
    db.customers.updateOne({"cus_name": "Abdulla Jassim"}, {$set: {"payment": 14} }) /* set payment = 14 where cus_name= 'Abdulla Jassim' Resutls If Match { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } Results If No Match { "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 } */  
    وبنفس الطريقة تستطيع تعديل اكثر من document دفعة واحده بإستخدام db.collection.updateMany
     
    رابعا: Delete
    في الحقيقة لا يوجد الكثير للحديث عنه في عملية الحذف لان الاتجاه والنتيجه واحده في كل الحالات حيث انه سيتم حذف الدوكيومنت التي تحدده
    db.collection.remove() - old db.collection.deleteOne() New in version 3.2 db.collection.deleteMany() New in version 3.2 و ساينتكس الحذف سيكون Syntax
    db.collection.deleteOne()  
    مثال على حذف احد الدوكيومنتس في Collection الـcustomers
    db.customers.deleteOne({_id: ObjectId("5803b8ccf9f236bb5591f186") }) /* Resutls If match { "acknowledged" : true, "deletedCount" : 1 } Resutls If !match { "acknowledged" : true, "deletedCount" : 0 */  
    مثال آخر على حذف اكثر من document دفعة واحده
    db.customers.deleteMany({"payment": {$not: {$eq: 0 } } }) /* Delete all document from customers where paymanet != 0 {$not: {$eq: 0 } } means != 0 Results If match { "acknowledged" : true, "deletedCount" : 5 } Results If !match (the statment is right but no such documents found) { "acknowledged" : true, "deletedCount" : 0 } */  
    مستوى المقال: مبتدئ
  3. ماهي قاعدة بيانات الـMongoDB؟
    في السابق كان الحديث حول قواعدة البيانات المعروفه و المتوارد بين اقطاب المبرمجين من مختلف الأصعدة ابتدا من web developers إلى الـsoftware developers على مختلف المنصات windows, OSX, Linux و جل الحديث كان يدور حول نوع واحد فقط وهو RDBMS Relational database management system مثل  MS SQL Server, IBM DB2, Oracle, MySQL, and Microsoft Access  التي تعتمد في حفظ البيانات داخل جداول ولكن في الآونة الأخيرة و بعد صدور عدد من JS Frameworks  و ارتفاع عدد مستخدمي لغة الجافاسكربت بدأت شركة 10GEN في العمل على قاعدة بيانات من نوع مختلف تماما عما سبق ذكرة وهي NoSQL تحت اسم MongoDB اي قاعدة بيانات لا توجد بها علاقة بين الجداول وتعتمد في حفظ البيانات كمستندات BOSN ويعد هذا النوع الأشهر بين عائلة الـNoSQL وهنا ننوه بأن جميع ما تعرفه عن الـSQL Databases قد يتغير فبالتاكيد لن يكون هناك كوريز بالطريقة التي اعتدت العمل عليها.
     
    1- أمثله
    وبما ان الكثير من المبرمجين لديه خلفية في الـMySQL سأقوم بمقارنة سريعة حول الأختلافات السطحية بين المونجو والـMySQL:
    اسم الـTable في الـMongoDB هو Collection اسم الـRow في الـMongoDB هو Document تعتمد قواعد بيانات الـRDBMS على الجداول كالنحو التالي:
     

     
    بينما قاعدة بيانات الـMongoDB تعتمد على BSON وهذا يعني Binary Encoding Of JSON Objects وتكون كالنحو التالي:
    { "_id" : ObjectId("57fe832b13e6a51130a23d2a"), "ID" : 1, "username" : "abdulla", "email" : "abdulla@gmail.com" } { "_id" : ObjectId("57fe832b13e6a51130a23d2b"), "ID" : 2, "username" : "omar", "email" : "omar.g@gmail.com" } { "_id" : ObjectId("57fe832b13e6a51130a23d2c"), "ID" : 3, "username" : "mohammed", "email" : "mohd@hotmail.com" }  
    امثلة حول الفروقات في عمليات الـQueries مابين الـMongoDB و الـMySQL OR RDBMS ولنفترض بأن لدينا جدول و كولكشن يحتويان على عدد من الصفوف والدوكيومنتس فيهم معلومات حول مستخدمين
    عرض جميع المستخدمين من هم دون السن الـ24 SELECT * FROM users WHERE age < 24 db.users.find({"age": { $lt: 24 }}) // $lt = less than  
    عرض جميع المستخدمين الذين  اعمارهم مابين الـ20 والـ30 SELECT * FROM `users` WHERE `age` BETWEEN 20 AND 30 db.users.find({ age: { $gt: 20, $lt: 30 }}) // $gt = greater than  
    عرض المستخدمين الذين اسمائهم تحتوي على حرف A في الاول او الاخير او المنتصف لايهم SELECT * FROM `users` WHERE username LIKE %A% db.users.find({username: /A/})  
    و في حالة الإضافة INSERT INTO `users` (username,age,status) VALUES ('abdulla',25,'active') db.users.insertOne({username: "abdulla", age: 25, status: "active"})  
    ولكن هناك فارق كبير في هذه الكويري و بما ان قاعدة بيانات الـMongoDB ليست Relational بالتالي ليس هناك Schema محدده عند الإضافه فتستطيع مثلا إضافة document بمتغير col,field ليس موجود في الـdocument السابق او التالي في نفس الـCollection وبهذا يقال للـMongoDB بأن اهم مميزات هذا النوع من قواعد البيانات بأنه Flexible او Dynamic Schema  ومثال على ذلك:
    db.users.insert([ { username: { fname: "abdulla", lname: "bahraini" }, age: 25, status: "active" }, { username: "mohammed", age: 19, status: "not active" } ])  
    2- لماذا التحول الى MongoDB ( وجهة نظر )

     
    كما اسلفنا سابقا ومع صدور عدد من js frameworks وبالاخص Meanjs المعني ب expressjs , angularjs & nodejs بالاضافه الmongodb و توسع هذه الفريموركس بشكل ضخم و رهيب جدا ومنها النود التي اصبحت خطر داهم على لغة الphp مقارنة بالسرعة, الاداء الرهيب وتناغم المونجو مع هذه الفريموركس بشكل افضل سبب في توجه الكثير من المطورين الى المونجو.
     
    ليس عند هذا الحد وحسب بل نظرا الى سرعة المونجو حسب الاحصائيات تبين اهمه الانتقال من قواعد البيانات الاعتيادية الى المونجو.
    تجربة اضافه 10000 صف و دوكيومنت في MySQL و MongoDB .. نلاحظ الفرق في سرعة الاداء احتاج المونجو الى ثانتين لتنفيذ المهمه بينما الMySQL احتاج الى 3 دقائق تقريبا.
     


     
    3-التثبيت
    لتثبيت الـMongoDB قم بالدخول على الرابط واختر ما يناسب نظام جهازك
     
    بعد التثبيت إن كنت  من متسخدمي الوندوز انشأ مجلد في داخل الـC (في حال تم تثبيت المونجو في السي)
     
    أضف المتغير التالي في PATH Environment وتجده في المسار التالي
    this pc >> proprieties >> Advanced System Settings >>  Advanced tab >> Environment Variables >> in System Variables find PATH then Click Edit
     
    افتح الـCMD واكتب الكوماند التالي لتفعيل خدمه الـMongoDB في جهازك وستعمل على بورت 27017 بشكل افتراضي
     
    ثم افتح CMD أخر واكتب الكوماند التالي للدخول على MongoDB SHELL
     

     
    بالتالي ستكون داخل الـMongoDB SHELL وتستطيع التعامل معه من خلال الاوامر المباشرة وللإطلاع اكثر اكتب help
     
    مستوى المقال: مبتدئ

عالم البرمجة

عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل