طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 122 · برمجة قواعد البيانات
الدرس 10 · الوحدة 5: إنشاء جداول البيانات

CREATE TABLE وأنواع البيانات

النوع الصحيح لكل عمود يمنع أخطاء لا يكتشفها أحد إلا بعد سنة. ⏱ نحو 35 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تكتب CREATE TABLE بأعمدة وأنواع وقيود.
  • تختار النوع المناسب للأعداد والمال والنصوص والتواريخ.
  • تستخدم IDENTITY لتوليد المفتاح وتعرف serial.
  • تقابل أنواع PostgreSQL بأنواع Oracle و MySQL.

١بنية CREATE TABLE

query.sql
CREATE TABLE suppliers (  id        int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,  name      varchar(80) NOT NULL,  phone     varchar(15),  rating    numeric(3,1),  is_active boolean DEFAULT true,  added_at  timestamptz DEFAULT now()); INSERT INTO suppliers (name, phone, rating) VALUES ('مؤسسة النور', '0501111111', 4.5);SELECT id, name, rating, is_active FROM suppliers;
النتيجة · صف واحد
idnameratingis_active
1مؤسسة النور4.5true

كل سطر: اسم العمود، ثم نوعه، ثم قيوده. لم نرسل id ولا is_active: الأول ولّدته القاعدة، والثاني أخذ قيمته الافتراضية.

٢اختيار النوع الصحيح

البياناتالنوع المناسبلماذا؟
عدد صحيح (كمية، معرّف)int، و bigint للأعداد الضخمةint حتى نحو 2.1 مليار
مال وأسعارnumeric(10,2)دقيق تمامًا. لا تستخدم real أو double للمال
قياس علمي تقريبيreal / double precisionأسرع لكنه تقريبي
نص قصير بحدvarchar(n)يرفض النص الأطول من n
نص حرtextبلا حد؛ ولا فرق في الأداء مع varchar في PostgreSQL
تاريخdateيوم بلا وقت
لحظة زمنيةtimestamptzتاريخ ووقت مع المنطقة الزمنية: الأفضل لأوقات الأحداث
نعم/لاbooleantrue أو false أو NULL
وثيقة مرنةjsonbبيانات بلا بنية ثابتة (الدرس 28)

لماذا لا نحفظ المال بـ real؟ لأن الأعداد العشرية الثنائية لا تمثّل 0.1 بدقة:

query.sql
SELECT 0.1::real + 0.2::real   AS بـ_real,       0.1::numeric + 0.2::numeric AS بـ_numeric;
النتيجة · صف واحد
بـ_realبـ_numeric
0.30.3

٣المفتاح المولَّد: IDENTITY أم serial؟

المعرّف الذي تولّده القاعدة يُكتب بطريقتين. serial هي القديمة الشائعة (ستراها في الكتب وفي قاعدة المتجر)، وGENERATED … AS IDENTITY هي المعيارية الحديثة في SQL وفي Oracle 12c فما بعد:

serialGENERATED ALWAYS AS IDENTITY
المعيارخاص بـ PostgreSQLمعيار SQL؛ موجود في Oracle أيضًا
إدخال قيمة يدويًّامسموح (قد يسبب تعارضًا لاحقًا)ممنوع إلا بأمر صريح
التوصيةللقواعد القديمةللتصاميم الجديدة
✗ خطأ
query.sql
CREATE TABLE t (id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, v text);INSERT INTO t (id, v) VALUES (5, 'يدوي');
✓ أُنشئ الجدول
✗ خطأ (السطر 2): cannot insert a non-DEFAULT value into column "id"
💡 تلميح: Use OVERRIDING SYSTEM VALUE to override.
✓ صواب
query.sql
CREATE TABLE t (id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, v text);INSERT INTO t (v) VALUES ('تلقائي');SELECT * FROM t;
✓ أُنشئ الجدول
✓ أُضيف صف واحد
النتيجة · صف واحد
idv
1تلقائي

ALWAYS يحمي المعرّف من الإدخال اليدوي الخاطئ.

توقّع وتحقّق

أنسب نوع لسعر منتج:

أنسب نوع لرقم جوال:

ليس عددًا تُجرى عليه عمليات.

الطريقة المعيارية لتوليد المعرّف:

المقابل في Oracle لـ varchar هو:

الخلاصة

تحدٍّ برمجي: جدول الكوبونات

متوسط

أنشئ جدول coupons لكوبونات الخصم بأنواع مناسبة.

المطلوب:
  • id معرّف مولَّد بـ IDENTITY ومفتاح أساسي.
  • code نص بحد 20 حرفًا، إلزامي.
  • discount مبلغ مالي دقيق بمنزلتين عشريتين (numeric).
  • expires_on تاريخ.
  • active منطقي قيمته الافتراضية true.
👀 اعرض الناتج المطلوب
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء
  • أنواع الأعمدة صحيحة
  • id يُولَّد تلقائيًّا، و active افتراضيًّا true
  • كود أطول من 20 حرفًا يُرفض
  • الكود إلزامي

💡 تلميح 1
الأنواع: varchar(20) و numeric(8,2) و date و boolean.
💡 تلميح 2
الافتراضي: active boolean DEFAULT true.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

solution.sql
CREATE TABLE coupons (  id         int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,  code       varchar(20) NOT NULL,  discount   numeric(8,2),  expires_on date,  active     boolean DEFAULT true);
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس