مقدمة في قواعد البيانات — SQL الأساسيات
مقدمة في قواعد البيانات العلائقية
قاعدة البيانات العلائقية تخزن البيانات في جداول مترابطة: كل جدول يمثل نوعاً من الأشياء (مستخدمون، طلبات)، وكل صف عنصر واحد، وكل عمود خاصية.
لماذا لا نحفظ كل شيء في ملف JSON؟
قاعدة البيانات تعطيك: استعلامات سريعة على ملايين الصفوف، وكتابة متزامنة من مستخدمين كثيرين دون تلف، وقيوداً تحمي صحة البيانات، ومعاملات (كل شيء أو لا شيء).
الأنظمة الشائعة
| النظام | ملاحظات |
|---|---|
| PostgreSQL | الأقوى والأكثر ميزات؛ يستخدمه Supabase |
| MySQL / MariaDB | منتشر جداً في الاستضافات |
| SQLite | ملف واحد بلا خادم — ممتاز للتعلم والتطبيقات الصغيرة والجوال؛ أمثلة هذه الدورة تعمل عليه |
| SQL Server / Oracle | بيئات الشركات |
لغة SQL متشابهة بينها بنسبة كبيرة، مع فروق في التفاصيل (مثل الترقيم التلقائي).
تصميم جدول
CREATE TABLE users (
id INTEGER PRIMARY KEY, -- مفتاح أساسي: فريد لكل صف
name TEXT NOT NULL, -- إلزامي
email TEXT NOT NULL UNIQUE, -- لا يتكرر
age INTEGER CHECK (age >= 13), -- شرط على القيمة
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);| القيد | يضمن |
|---|---|
| PRIMARY KEY | هوية فريدة لكل صف |
| NOT NULL | القيمة موجودة |
| UNIQUE | لا تكرار (البريد) |
| CHECK | شرط منطقي |
| DEFAULT | قيمة تلقائية |
| REFERENCES (مفتاح أجنبي) | القيمة موجودة في جدول آخر |
القيود خط الدفاع الأخير: حتى لو أخطأ كود التطبيق، ترفض القاعدة البيانات الفاسدة.
الترقيم التلقائي: فرق بين الأنظمة
| النظام | الصيغة |
|---|---|
| SQLite | id INTEGER PRIMARY KEY |
| PostgreSQL | id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY (أو SERIAL القديم) |
| MySQL | id INT AUTO_INCREMENT PRIMARY KEY |
العلاقات بالمفتاح الأجنبي
CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
CREATE TABLE books (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
author_id INTEGER NOT NULL REFERENCES authors(id) ON DELETE RESTRICT
);| نوع العلاقة | التنفيذ |
|---|---|
| واحد لمتعدد (مؤلف ← كتب) | مفتاح أجنبي في جدول "المتعدد" |
| متعدد لمتعدد (طلاب ↔ دورات) | جدول وسيط (enrollments) فيه مفتاحان أجنبيان |
| واحد لواحد | مفتاح أجنبي فريد |
ON DELETE: RESTRICT (امنع حذف مؤلف له كتب)، CASCADE (احذف كتبه معه)، SET NULL. (في SQLite فعّل المفاتيح الأجنبية بـ PRAGMA foreign_keys = ON;.)
التطبيع باختصار
لا تكرر المعلومة: اسم المدينة لا يُكتب نصاً في 10,000 صف ثم يُعدَّل في بعضها فقط. ضع الأشياء المستقلة في جداولها واربطها بالمعرّفات.
تمرين
صمم جداول لمكتبة: مؤلفون، كتب، أعضاء، واستعارات (عضو يستعير كتاباً بتاريخ ويعيده لاحقاً). حدد المفاتيح والقيود، ونفّذها على SQLite.
PRAGMA foreign_keys = ON;
CREATE TABLE authors (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE books (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
published_year INTEGER CHECK (published_year BETWEEN 1400 AND 2100),
author_id INTEGER NOT NULL REFERENCES authors(id) ON DELETE RESTRICT
);
CREATE TABLE members (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
);
-- متعدد لمتعدد عبر جدول وسيط مع بيانات إضافية (التواريخ)
CREATE TABLE loans (
id INTEGER PRIMARY KEY,
book_id INTEGER NOT NULL REFERENCES books(id),
member_id INTEGER NOT NULL REFERENCES members(id) ON DELETE CASCADE,
borrowed_at TEXT NOT NULL DEFAULT (date('now')),
returned_at TEXT
);
INSERT INTO authors (id, name) VALUES (1, 'طه حسين'), (2, 'نجيب محفوظ');
INSERT INTO books (title, published_year, author_id) VALUES
('الأيام', 1929, 1), ('اللص والكلاب', 1961, 2), ('بين القصرين', 1956, 2);
INSERT INTO members (name, email) VALUES ('سارة', 'sara@example.com'), ('عمر', 'omar@example.com');
INSERT INTO loans (book_id, member_id) VALUES (2, 1), (3, 2);
SELECT b.title, a.name AS author FROM books b JOIN authors a ON a.id = b.author_id;اختبر فهمك