Professional Documents
Culture Documents
مقدمة
إن SQLوتعني لغة االستعالمات الهيكلية Structured Query Languageوهي من وضع
( IBMفي نظام لهم اسمه النظام Rيعود للسبعينات من القرن الماضي) وهي لغة عيارية منذ ٦٨٩١م
حيث تبنتها ANSIثم ISOفي معايير متالحقة.
يجدر بنا اإلشارة إلى أن SQLليست لغة برمجة وإنما لغة للتحدث مع قواعد البيانات العالئقية
RDBMS.
ويوجد العديد من قوا عد البيانات التي يمكنك مخاطبتها بهذه اللغة سواء الحرة مثل MySqlو
PostgreSQLأو المملوكة مثل الشهيرة Oracleوهناك قواعد بيانات تدعم SQLكميزة إضافية
غير أساسية.
بعكس ما قد يخطر ببالك ليس بالضرورة أن تكون قواعد البيانات برمجيات عبر شبكة فهناك منها ما هي
هيئة ملفات تستخدمها تماما كما تكتب قيم بينها فواصل CSVفي ملف لكنها تكون أسرع وأكثر كفاءة
وفعالية .منها قواعد بيانات SQLiteالتي أطلقت عام ١٠٠٦م بعد قيام مؤلفها بأبحاث لصالح البحرية
للتحكم بالمدمرات الصاروخية.
اخترنا SQLiteلعدة أسباب
ال تحتاج التعقيدات المرتبطة بنموذج الخادم والعميل client/serverفهي في النهاية مجرد
ملف.
مع أنها صممت كي تكون منضدة إال أنه يمكنها التعامل مع كم كبير من البيانات
تدعم معايير ٨١ SQL-بشكل كبير.
كل ما يلزمنا في هذه الوثيقة برنامج صغير اسمه (٣ sqliteفي فيدورا/أعجوبة تجده في حزمة )sqlite
وهناك إضافة متصفح اإلنترنت لثعلب النار firefoxتسمح لك بالتعامل رسوميا مع ملفاتSQLite.
األساسيات
تتألف قاعدة البيانات من عدد من الجداول كل منها له مخطط ثابت schemaيحدد ما يحتويه كل جدول
من حقول (أعمدة).
أنواع الحقول
في SQLالقياسية يجب تعريف أنواع الحقول بشكل مسبق وااللتزام بها.
Formation 01 taghit
Sql /sqllit yahi mohammed
><noteتسمح لك SQliteبعدم االلتزام بنوع الحقل المعرف في المخطط Schemaكأن تضع نص
في حقل عددي وهو ما يعرف بميزة > dynamic typing. </noteمن مرونة SQliteفإنها توفر
األنواع اإلضافية التالية:
حقل نصي عالمي حر الطول TEXTوهو يدعم unicodeدون الحاجة لتحديد أي طول.
(هذا النوع متوفر في MySQLو)PostgreSQL
حقل ثنائي BLOBلحفظ سلسلة من البيانات (ليس بالضرورة أن تكون نصا كحفظ محتويات
ملف .jpgمثال)
حقل عددي صحيح INTEGER
وحقل عددي نسبي REAL
ال توفر SQLiteدعما حقيقيا لحفظ التاريخ والوقت لكن يمكنك محاكاة ذلك عبر استعمال INTEGER
وحفظ عدد الثواني بعد ما يعرف ببزوغ فجر يونكسUnix epoch.
يمكنك استعمال أنواع SQLالقياسية لكن اعلم أن SQLiteستدير الحجم ولن تحترم النوع أو الحد
الذي تطلبه.
><note tipيفضل البعض استخدام حقول من قوى ١مثل() ٦١٩ VARCHARإال أن هذا في
SQLiteليس منه فائدة ألنها كلها من نوع>TEXT </note
فيSQLite
في sqliteيكفي تنفيذ ٣ sqliteمتبوعا باسم الملف المطلوب إنشاؤه ليكون قاعدة بيانات
sqlite3 my_db_file.db
وألغراض االختبار يمكنك استعمال جدول في الذاكرة المتطايرة RAMوذلك بتمرير :memory:
عوضا عن اسم الملف هكذا
sqlite3 :memory:
يتوفر واجهة رسومية تتعامل مع ملفات sqliteوهي متوفرة بصيغتين أسهلهما إضافة لمتصفح اإلنترنت
( firefoxداخل قائمة أدوات ) toolsأو برنامج مستقل (يتم تنفيذه عبر)xulrunner
https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
Formation 01 taghit
Sql /sqllit yahi mohammed
http://code.google.com/p/sqlite-manager/
MySQLفي
root. يمكنك تحديد مستخدم غير. حتى يسألك عن كلمة السرp أضف الخيار
ثم ننشئ قاعدة البيانات باألمر
. </note> <note بأحرف كبيرةSQL <جرت العادة أن تكتب الكلمات المحجوزة فيnote tip>
; </note> بفاصلة منقوطةSQL تتبع كل عباراتimportant>
حيث جدول بها هكذاSHOW DATABASES ولعرض بقواعد البيانات المتوفرة نستعمل
Formation 01 taghit
Sql /sqllit yahi mohammed
>mysql
الختيار قاعدة بيانات نستعمل USEمتبوعا باسم قاعدة البيانات ويمكن عمل هذا االختيار عند االتصال
بخادم mysqlبكتابة اسم قاعدة البيانات في نهاية األمر
إنشاء الجداول
إلنشاء جدول نستخدم CREATE TABLEويمكن إنشاء جدول مؤقت متطاير المحتوى عبر
CREATE TEMPORARY TABLEوهو جدول حذف تلقائيا عند إنهاء االتصال (إغالق
البرنامج).
ويمكن أن نضيف أيضا IF NOT EXISTSحتى ال يعطي خطأ إن كان الجدول موجودا مسبقا .بعدها
نذكر اسم الجدول وبين قوسين نكتب تعريف لألعمدة الموجودة فيه
><note tipتعتبر لغة SQLمن اللغات حرة التنسيق Free formلهذا يجوز أن تكتب العبارة
الواحدة على عدة أسطر>. </note
يمكنك وصف عمود ما بأنه معرّف أساسي PRIMARY KEYأو بأنه فريد UNIQUEأو مفهرس
KEYأو أنه ال ينبغي أن يكون خاليا NOT NULLكما يمكنك أن تعطيه قيمة أولية كذلك يمكن جعله
ذاتي الزيادة( AUTOINCREMENTأو كما في mysqlيكتب AUTO_INCREMENT
بعالمة تحتية _) وسيأتي تفصيل ذلك.
><note tipيسمى األمر السابق باسم Data Definition Languageأو DDLاختصارا .
></note
إضافة الصفوف
Formation 01 taghit
Sql /sqllit yahi mohammed
يمكننا إضافة الصفوف إلى الجدول عبر INSERT INTOمتبوعة باسم الجدول ثم VALUESثم
القيم بين قوسين
لكن إن كنت تريد تحديد قيم ألعمدة بعينها وترك الباقية للقيم التلقائية (مثل المعرف ذاتي الزيادة) يمكنك
تحديد األعمدة التي تريدها بين قوسين بعد اسم الجدول هكذا
عرض كل الصفوف
لعرض كل الصفوف من جدول ما (مثل جدول addressbookمن المثال السابق) يمكننا كتابة
SELECTمتبوعة بأسماء األعمدة أو * الختيار كل األعمدة متبوعة بكلمة FROMمتبوعة باسم
الجدول هكذا
ألغراض النسخ االحتياطي أو التصدير يمكنك استخراج أوامر SQLالتي تلزم إلعادة بناء قاعدة البيانات
بكل جداولها بكل صفوفها ويسمى هذاdump.
في SQLiteيكون ذلك عبر األمر الخاص( .dumpأي نقطة متبوعة بكلمة ) dumpاكتبه في محث
٣sqliteثم اضغط ENTERدون وضع فاصلة منقوطة.
ويعمل أيضا من سطر األوامر مثال في سطر أوامر نظام التشغيل (وليس ) SQLiteاكتب
Formation 01 taghit
Sql /sqllit yahi mohammed
إن كنت تحتاج عرض مخطط قاعدة البيانات بكل جداولها لكن دون الصفوف اكتب في محث٣ sqlite
األمر الخاص( .schemaأي نقطة متبوعة بكلمة schemaمتبوعة بالضغط على)ENTER
حذف جدول
لتسريع الوصول لصف يحتوي على قيمة معينة لحقل ما في جدول ما يجب أن يكون ذلك الحقل مفهرسا
مثال للحصول على الصف الذي يحتوي القيمة omarلعمود nameفي جدول addressbookفإن
قاعدة البيانات ستسير على كل الصفوف بحثا عن تلك القيمة في الجدول لكن إن كان هناك فهرس على
حقل االسم فإنها ستجده مباشرة دون المرور على كل الصفوف .ليس المساواة فقط بل المقارنة مثال
للحصول على كل الصفوف في جدول العالمات التي تزيد تزيد العالمة عن ٩٠فإن كانت العالمة
مفهرسة لن يتم مقارنة كل الصفوف بل يتم استخدام الفهرس لمعرفة تلك الصفوف مباشرة .أيضا تفيد
الفهرسة تسريع في الترتيب التصاعدي أو التنازي للحقل المفهرس.
يكون إنشاء الفهرس عبر استخدام CREATE INDEXأو CREATE UNIQUE INDEXثم
اسم الفهرس (اسم فريد ضمن نفس الجدول يجوز أن يكون اسم الحقل) ثم كلمة ONثم بين قوسين
الحقول التي تعمل الفهرسة عليها مثال:
هنا عملنا فهرسا فريدا ضمنيا على حقل االسم ألننا استعملنا كلمة UNIQUEعند انشاء الجدول .وعملنا
فهرسا غير فريد على حقل التكرار nعبر CREATE INDEXبعد إنشاء الجدول.
><note warningمن األخطاء الشائعة عند تعلم إنشاء الفهارس في SQLهو أن األقواس بعد
ONتسمح لك بعمل أكثر من فهرس على أكثر من حقل وهذا خطأ بل هي تعمل فهرس واحد مركب
من تجميع الحقول >. </noteالحظ هذا المثال
لكن لو أردنا أن نعمل فهرسا فريدا لالسم األول وآخر لالسم الثاني
Formation 01 taghit
Sql /sqllit yahi mohammed
),٠٣first_name VARCHAR(
),٠٣last_name VARCHAR(
UNIQUE (first_name),
UNIQUE (last_name)
);
CREATE UNIQUE INDEX first_name ON users (first_name)
CREATE UNIQUE INDEX last_name ON users (last_name);
:والذي يكافئ
: لكن المثال التالي.لكن هذا ليس ما نريده فهو يمنع تكرار االسم األول حتى لو اختلف االسم الثاني
هنا الفريد ليس الحقل األول أو الثاني بل تركيبهما معا أي يجوز أن يكون االسم األول مكررا إن اختلف
الجدول السابق يمكن إنشاؤه بأمر واحد هكذا.الثاني
يكون سريعا كذلك الوصولahmad والثانيomar هنا الحصول على الصف الذي فيه االسم األول
مهما كان االسم الثاني أيضا يكون سريعاali لكل الصفوف التي فيها االسم األول
ثمb ثمa <ترتيب الحقول مهم في الفهرس فإن كان عندك فهرس واحد على ثالث حقول هيnote>
بسرعة لكن ليسc والb دون تحديدa فإنك تستطيع البحث أو الترتيب بسرعة على السوابق أي قيمc
a. </note>دون تحديدb
Formation 01 taghit
Sql /sqllit yahi mohammed
المفتاح الرئيسي ما هو إال فهرس فريد يستخدم لجلب الحقول سريعا .في الغالب يكون هذا الحقل حقل
رقمي متزايد تلقائيا .ويجوز أن يكون على حقل عددي أو نصي أو حتى تركيب عدة الحقول (متجانسة
النوع أو غير متجانسة النوع).
هناك صيغتين لتعريفه بعد الحقل مباشرة هكذا
أو بعد الحقول بطريقة تشبه تعريف الفهارس ويمكن أن تكون مركبة بذكر أكثر من حقل
االستعالم
االستعالم يكون عبرSELECT
;١+١SELECT
();١,-٠,٩,١SELECT MAX
;)"SELECT LENGTH("ojuba
Formation 01 taghit
Sql /sqllit yahi mohammed
يمكن عرض كل الحقول عبر * ويمكن تحديد الحقول المطلوبة عبر سردها مفصولة بعالمة,
الترتيب
يمكنك ترتيب الصفوف عبر ORDER BYمتبوعة باسم الحقل ثم( ASCوهو التلقائي) أو DESC
للتصاعدي أو التنازلي على الترتيب.
في هذا المثال نرتب على االسم األول فإن تساوى على األخير.
يمكن وضع حد أعلى لعدد الصفوف المجلوبة عبر عبارة LIMITمثال الستخراج صف واحد يمكنك
كتابة
يمكن تخطي عدد من الصفوف بواسطة عبارة اإلزاحة OFFSETمتبوعة بعدد الصفوف المتخطاة.
مثال العبارة السابقة تكافئ
أما الصفحة الثالثة فتكون بتخطي ٦٠صفوف ( ٥في كل صفحة) لعرض الصفوف حتى الخامس عشر.
ويمكن وضع فاصلة ,مكان عبارة OFFSETلكن ترتيب التعبيرين مقلوب (اإلزاحة أوال ثم الحد)
لعرض رقم آخر صف يمكن استخدام الترتيب العكسي مع وضع حد أعلى صف واحد
Formation 01 taghit
Sql /sqllit yahi mohammed
الشرطWHERE
يمكن عرض الصفوف التي تطابق شرط معين عبر عبارة WHEREمتبوعة بالشرط أو الشروط
المركبة عبر ANDأو ORويمكن استخدام األقواس.
مثال لعرض الصفوف التي يكون االسم األخير فيها omarنكتب االستعالم
> <note tipمطابقة نمط السوابق (كما في المثال السابق) يستفيد من الفهارس أما اللواحق أو التوسط
فال يستفيد>. </note
><note tipقبل أن تتندر على كود NULL=NULLتعطي FALSEعليك تخيل أن NULLتمثل
قيمة مجهولة خالية .فإن القيمة المجهولة ال تساوي القيمة المجهولة األخرى .لهذا نستعمل أداة IS
>NULL </note
ربط الجداولJOIN
يمكن مقابلة جدولين أو أكثر كل صف في األول مع كل صفوف اآلخر كما في الضرب الديكارتي .لنأخذ
المثال التالي:
() PRIMARY KEY, price DOUBLE, in_stock IN٩٣CREATE TABLE items (name VARCHAR
;)TEGER
(), NUMBER INTEGER);٩٣CREATE TABLE cart (item_name VARCHAR
);١٣٣٣, ٩.٠INSERT INTO items VALUES ('milk',
);٠٣٣٣, ٠.١INSERT INTO items VALUES ('chicken',
);٠INSERT INTO cart VALUES ('milk',
);١INSERT INTO cart VALUES ('milk',
);٩INSERT INTO cart VALUES ('chicken',
Formation 01 taghit
Sql /sqllit yahi mohammed
itemsجدول األصناف
name price in_stock
milk ٩.٠ ١٣٣٣
chicken ٠.١ ٠٣٣٣
cartجدول عربة التسوق
item_name number
milk ٠
milk ١
chicken ٩
مقابلة الجدولين تكون هكذا
والتي تعطي
name price in_stock item_name number total_price
milk ٩.٠ ١٣٣٣ milk ٠ ٥.٠
milk ٩.٠ ١٣٣٣ milk ١ ٩.٠
milk ٩.٠ ١٣٣٣ chicken ٩ ٠.٣
chicken ٠.١ ٠٣٣٣ milk ٠ ١٠.٠
chicken ٠.١ ٠٣٣٣ milk ١ ٠.١
chicken ٠.١ ٠٣٣٣ chicken ٩ ١٣.٩
!لكن هناك صفوف ال نريدها فلماذا نضرب عدد الدجاجات في سعر الحليب
لمطابقة اسم الصنفWHERE أول ما يخطر بالبال هو استعمال
إن كان هناك تشابه في األسماء فإننا بحاجة إلزالة الغموض وذلك بذكر اسم الجدول أو كنيته ثم نقطة ثم
name عوضا عنitems.name اسم الحقل مثال
Formation 01 taghit
Sql /sqllit yahi mohammed
يمكنك أن تعطي الجدول أو الحقل كنية وذلك بذكر الكنية بعد عبارة ASكما فعلنا في حاصل ضرب
العدد في سعر price*numberوسميناه السعر اإلجماليtotal_price
أنواع الربط
الربط الداخلي( INNER JOINالنوع التلقائي)
اآلن لننفذ أمر الربط السابق والذي يكافئ تحديد نوع الربط على أنه INNER JOINألنه التلقائي
نالحظ أن النتيج ة هي نفسها كما كانت قبل إضافة الحقول غير المتقابلة ولم نجد صنف beansألنه لم
يظهر في عربة التسوق وال وجدنا الجبن الذي ظهر في العربة ولم يظهر في األضناف
لنقم اآلن بإضافة صفوف متقابلة لكن بقيمة خالية NULLفي حقول التقابل
الربط الخارجي يربط الصفوف إن كان وإن كان أحد طرفي المقابلة خاليا NULL.أما الربط األيسر
فيمر على كل صفر في طرف المقابلة األيسر حتى وإن كان الطرف األيمن خال .والمقابلة اليمنى بالعكس.
Formation 01 taghit
Sql /sqllit yahi mohammed
الحظ أن الجبن لم يكن بين النتائج ألنه في الطرف األيمن وال مقابل له في الطرف األيسر.
الصف األيسر الذي حقل المقابلة في خال NULLموجود لكنه لم يتم مقابلته مع األيمن الذي
حقل المقابلة فيه NULLبل كان ما يقابله حقول كلها خالية ذلك أن NULLال تساوي NULL
بل تفحصل بIS NULL
والتي تعطي (حيث جمع مدخلتا الحليب في مدخلة واحدة عوضا عن ٦و ٣أصبحت مدخلة واحدة عددها
)٤
item_name total_number
NULL ١
cheese ١
chicken ٩
milk ٠
><note importantالحقول غير المذكورة في التجميع يجب أن تجلب عبر دالة تجميع وإال فإنها
ستكون واحد عشوائية من بين الصفوف المجمعة>. </note
إن استخدام أي دالة تجميع مثل SUMدون ذكر التجميع يؤدي إلى عملية تجميع لكل الصفوف .لذا
يمكننا طباعة السعر اإلجمالي للفاتورة كاملة باالستعالم التالي:
Formation 01 taghit
Sql /sqllit yahi mohammed
ال يجوز استخدام أي من دوال التجميع مثل SUMفي عبارة WHEREألنها تنفذ قبل التجميع
GROUP BYوهنا جاءت الحاجة لعبارة HAVINGوالتي تذكر بعدGROUP BY
><note tipترتيب الشروط هو ONالتي تستخدم مقرونة مع JOINثم WHEREوالتي تحدث
قبل GROUP BYوأخيرا تنفذ>HAVING </note
اإلضافة من استعالم
يمكنك أخذ نواتج عملية االستعالم (بكل مزاياها) وتمريرها إلى INSERT INTOوذلك بوضع عبارة
SELECTمكان VALUESوذلك جائز سواء من نفس الجدول أو من جدول آخر أو من عملية دمج
… JOINإلخ
>;٠INSERT INTO t1 (col1, col2) SELECT t2.c1, t2.c2 FROM t2 WHERE t2.c1
لكن السرعة ليست هي الفائدة الوحيدة .مثال فلتكن إضافة ٥صفوف لكن إضافة الصف الرابع فشلت
لسبب أو آلخر (كأن يكون حقل فريد مكرر) إن كنا نريد ضمان دخول الخمسة بحركة واحدة إما كلها
وإما ال شيء فإننا نستعمل ROLLBACKكي نعود إلى الحالة التي كان عليها قبل الحركة.
الحظ أن االستعالم في آخر المثال التالي لم يعد أي نتائج.
Formation 01 taghit
Sql /sqllit yahi mohammed
;sqlite> ROLLBACK
;sqlite> SELECT * FROM t1
العالقات
عالقة واحد إلى واحدOne to One
عالقة واحد إلى العديدOne to Many
عالقة العديد إلى واحدMany to One
عالقة العديد إلى العديدMany to Many
atomicity
consistency
isolation
durability
Formation 01 taghit