يعني إيه داتابيز علائقية؟
قبل أي كويري: الداتا متخزنة إزاي، وليه في جداول، وليه كل عمود ليه نوع، وليه الصفوف ملهاش ترتيب. الحاجات دي هي اللي هتفسّرلك بعدين نص الأخطاء اللي هتقابلها.
- تقرا أي جدول وتفهم كل صف بيمثّل إيه، وكل عمود معناه إيه
- تعرف أنواع الداتا الأساسية في PostgreSQL، وليه الفلوس مينفعش تتخزن float
- تفهم ليه الصفوف ملهاش ترتيب مضمون، ويعني إيه NULL
- تكتب أول كويري:
SELECTأعمدة معينةFROMجدول
الداتا متخزنة في جداول
الداتابيز العلائقية (Relational Database) بتخزّن كل حاجة في جداول. وكل جدول بيمثّل نوع واحد من الحاجات: جدول للمنتجات، وجدول للعملاء، وجدول للطلبات.
- الصف (Row): حاجة واحدة بعينها. يعني صف واحد = لابتوب واحد.
- العمود (Column): صفة من صفات الحاجة دي، زي الاسم أو السعر أو الرامات. وكل عمود ليه نوع ثابت.
دي الجدول products في داتابيز الكورس. الكويري دي اتشغّلت لوحدها أول ما وصلت هنا، وده PostgreSQL حقيقي شغال جوه الصفحة:
SELECT * FROM products;
عدّل فيها براحتك وشغّلها تاني بـ Ctrl + Enter. كل تشغيل بيحصل جوه Transaction وبيتلغي في الآخر (ROLLBACK)، فمهما كتبت مش هتبوّظ الداتا.
ليه مش Excel؟
شيت Excel شكله جدول برضه. الفرق في الحاجات اللي الداتابيز بتمنعها وبتضمنها:
| Excel | داتابيز | |
|---|---|---|
| نوع الداتا | أي خانة تقبل أي حاجة | العمود ليه نوع، و 'abc' مش هتدخل في عمود رقم |
| القواعد | مفيش | قيود: مفيش id متكرر، السعر أكبر من صفر، الطلب لازم يبقى لعميل موجود |
| ناس كتير مع بعض | ملف واحد بيتقفل | آلاف بيقروا ويكتبوا في نفس اللحظة من غير ما يبوّظوا بعض |
| الحجم | مليون صف وبيتقل | مليارات الصفوف |
| السؤال | فلاتر وزراير | لغة كاملة (SQL) تسأل بيها أي سؤال |
استكشف داتابيز الكورس
الكورس كله شغال على داتابيز محل لابتوبات: 7 جداول. دوس على أي جدول تشوف صفوفه. ولو وقفت على عمود عليه FK، الجدول اللي بيشاور عليه هينوّر. ودوس على أي قيمة صفرا في الجدول اللي تحت، هتنقلك للصف اللي بتشاور عليه.
PK = Primary Key (هوية الصف). FK = Foreign Key (بيشاور على صف في جدول تاني). NULL = العمود ده مسموح يبقى فاضي. هنشرح الاتنين الأولانيين بالتفصيل في الدرس الجاي.
الداتا دي متوسّخ فيها عن قصد، زي أي داتا حقيقية: منتج ملوش سعر، وعميل ملوش مدينة، وطلب مفيهوش منتجات، وعميل اسمه مكتوب small. كل حاجة من دول هتبقى فخ في درس من الدروس الجاية.
كل عمود ليه نوع
النوع بيحدد إيه اللي ينفع يتخزن، وإيه العمليات اللي تنفع عليه. ودي الأنواع اللي في داتابيز الكورس:
| النوع | بيخزّن إيه | مثال في الداتا |
|---|---|---|
integer |
رقم صحيح | stock، ram_gb |
numeric(10,2) |
رقم عشري مضبوط: 10 أرقام، منهم 2 بعد العلامة | price، salary |
text |
نص بأي طول | name، city |
date |
تاريخ من غير وقت | released_on |
timestamp |
تاريخ ووقت | ordered_at |
boolean |
true أو false |
(هيظهر لما نحسب شروط) |
جرّب الكويري دي. الدالة pg_typeof بترجع نوع أي قيمة:
SELECT name, price, price * 2 AS double_price, pg_typeof(price) AS price_type, released_on, pg_typeof(released_on) AS date_type FROM products;
ليه الفلوس مينفعش تتخزن float؟
الكمبيوتر بيخزّن الـ float بالـ Binary، وفيه أرقام عشرية مينفعش تتمثّل بالظبط، زي 0.1. شوف بعينك:
SELECT 0.1::float8 + 0.2::float8 AS float_sum,
0.1::numeric + 0.2::numeric AS numeric_sum,
(0.1::float8 + 0.2::float8) = 0.3 AS float_equals,
(0.1::numeric + 0.2::numeric) = 0.3 AS numeric_equals;0.30000000000000004، والمقارنة بـ 0.3 طلعت false. في بنك أو متجر بيعمل ملايين العمليات، الفرق الصغير ده بيتجمّع. علشان كده الفلوس دايماً numeric (أو decimal، وهو نفس النوع).
ولو حطيت قيمة من نوع غلط، PostgreSQL بيرفض. شغّل دي وشوف الخطأ متشرح إزاي:
SELECT name, price + 'abc' FROM products;
عايز تخزّن رقم تليفون العميل زي 01012345678. أنهي نوع الأنسب؟
text. رقم التليفون مش رقم بنحسب بيه، مفيش حد بيجمع تليفونين. ولو خزنته integer الصفر اللي في الأول هيضيع (1012345678)، والأرقام الدولية فيها +. القاعدة: لو مش هتعمل عليه حسابات، يبقى text. وده نفس سبب إن phone في داتابيز الكورس text.
الصفوف ملهاش ترتيب
الجدول مجموعة، والمجموعة ملهاش أول وآخر. الصفوف متخزنة على الـ Disk بالترتيب اللي يريّح الداتابيز، والترتيب ده ممكن يتغيّر بعد UPDATE أو DELETE أو حتى مع تغيير خطة التنفيذ.
شغّلت SELECT * FROM customers; مرتين ورا بعض، وطلعوا بنفس الترتيب. ده معناه إيه؟
مفيش ضمان. الـ Standard بتاع SQL بيقول صراحة إن النتيجة من غير ORDER BY ملهاش ترتيب محدد. اللي شايفه هو ترتيب التخزين الحالي، وده تفصيلة داخلية مش وعد.
NULL: القيمة اللي مش معروفة
بص على عمود phone في الكويري دي:
SELECT id, name, city, phone, email FROM customers;
NULL مش صفر، ومش نص فاضي ''. معناه: القيمة دي مش معروفة. عميل phone بتاعه NULL ممكن يكون معندوش تليفون، وممكن يكون عنده بس ما سجّلهوش. الداتابيز مش عارفة.
سعر المنتج Lenovo Yoga Slim 7 قيمته NULL. لو حسبنا price * 2 ليه، النتيجة هتبقى إيه؟
NULL. أي عملية حسابية فيها قيمة مش معروفة، نتيجتها مش معروفة. “ضعف رقم مش معروف” = مش معروف. شغّل كويري الأنواع اللي فوق تاني، وبص على الصف ده في عمود double_price. القاعدة دي بالذات هي سبب أخطاء صامتة كتير، وليها درس كامل في المرحلة الجاية.
أول كويري بإيدك
الشكل الأساسي:
SELECT عمود1, عمود2 -- الأعمدة اللي عايزها، أو * لكلهم
FROM اسم_الجدول;
*معناها “كل الأعمدة”. مفيدة وانت بتستكشف، بس في الكود الحقيقي اكتب الأعمدة بالاسم: أوضح، وأسرع، ومش هتتكسر لو حد ضاف عمود.- الـ
;في الآخر بتقفل الـ Statement. - الكلمات المحجوزة (
SELECT،FROM) مش حساسة لـ Capital و Small. بس العُرف إنها تتكتب Capital علشان تبان.
التمارين دي بتتصحح لوحدها: الموقع بيشغّل حلك والحل الصح على نفس الداتا ويقارن النتيجتين. ترتيب الصفوف مش مهم هنا، بس الأعمدة لازم تبقى نفس العدد وبنفس الترتيب.
تمرين تطبيقي
سهل✓ اتحلاعرض اسم كل ماركة والبلد بتاعتها.
SELECT name, country FROM brands;
تمرين تطبيقي
سهل✓ اتحلالمخزن عايز يعرف عنده إيه: اعرض اسم كل منتج، وسعره، والكمية اللي في المخزن.
SELECT name, price, stock FROM products;
تمرين تطبيقي
سهل✓ اتحلقسم الـ HR عايز ليستة الموظفين: الـ id، والاسم، والوظيفة، والمرتب.
SELECT id, name, role, salary FROM employees;
تمرين تطبيقي
متوسط✓ اتحلاعرض اسم كل منتج، وسعره، وسعره بعد ضريبة 14% في عمود اسمه price_with_vat. لاحظ المنتج اللي سعره NULL، هيطلع إيه في العمود الجديد؟
SELECT name, price, price * 1.14 AS price_with_vat FROM products;