Menu
flag Ar iconالعربيةdown icon

إنشاء جدول في SQLite: شرح CREATE TABLE بالأمثلة

تعلّم كيفية إنشاء الجداول في SQLite: تعريف الأعمدة، القيود، IF NOT EXISTS، الجداول المؤقتة، وإنشاء جدول من نتيجة استعلام SELECT.

تحتوي هذه الصفحة على محررات قابلة للتشغيل — حرّر، شغّل، وشاهد النتيجة فوراً.

أمر CREATE TABLE لتعريف بنية الجدول

أي بيانات منظّمة في SQLite تُخزَّن داخل جداول، وكل جدول تبدأ حياته بجملة CREATE TABLE. تختار له اسمًا، وتحدّد الأعمدة، ثم تُضيف القيود (constraints) إن احتجت لها. بعدها يكتب SQLite بنية الجدول داخل ملف قاعدة البيانات، ويصبح الجدول جاهزًا للاستخدام مباشرة.

وإليك أبسط مثال عملي:

ثلاثة أعمدة، مفتاح أساسي واحد، وقيد NOT NULL واحد. SQLite ملأ قيمة id تلقائيًا لأنه مفتاح أساسي من نوع integer، وسمح للحقل email أن يكون NULL في الصف الثاني لأنه لا يوجد ما يمنع ذلك. هذا هو الشكل العام كاملًا — اسم الجدول، الأعمدة، القيود — وكل ما تبقى في هذه الصفحة ما هو إلا تنويعات على هذا النمط.

شرح صياغة أمر CREATE TABLE خطوة بخطوة

تعريف العمود يأخذ الصيغة name TYPE constraint constraint .... تحديد النوع اختياري في SQLite الكلاسيكي (سنتحدث عن ذلك بالتفصيل في صفحة type affinity)، لكن من الأفضل دائمًا أن تذكره صراحةً — فالقارئ والأدوات تعتمد عليه.

بعض النقاط المهمة التي تستحق الانتباه:

  • القيود تتسلسل بفواصل المسافات: مثلاً NOT NULL UNIQUE على عمود sku يعني تطبيق الشرطين معاً.
  • وضع DEFAULT 1 على عمود in_stock يسمح لعبارة INSERT بتجاهل هذا العمود.
  • SQLite يستخدم INTEGER للقيم المنطقية، إذ لا يوجد نوع BOOLEAN أصلي. القيمة 0 تعني false، والقيمة 1 تعني true.
  • وضع فاصلة زائدة بعد آخر عمود يُعتبر خطأً نحوياً. لغة SQL أكثر صرامة من JavaScript في هذا الجانب.

استخدام IF NOT EXISTS لتجنّب الأخطاء عند إعادة التشغيل

عند تنفيذ أمر CREATE TABLE على قاعدة بيانات تحتوي الجدول مسبقاً، يُطلق SQLite خطأً:

خطأ: الجدول users موجود بالفعل

هذا مقبول في المرة الأولى، لكنه مزعج في المرة المئة. تأتي IF NOT EXISTS لتجعل العبارة بلا أي تأثير إذا كان الجدول موجودًا أصلًا:

عبارة CREATE TABLE الثانية لا تفعل شيئًا — لا خطأ ولا تعديل في البنية. هذه هي الصيغة التي تحتاجها في كود الإقلاع، وسكربتات الترحيل (migrations)، وأي مكان قد يُنفَّذ فيه نفس الاستعلام أكثر من مرة.

لكن انتبه: IF NOT EXISTS يتحقق من الاسم فقط. إذا كان هناك جدول بنفس الاسم لكن بأعمدة مختلفة، فإن SQLite يتركه كما هو. لن "يُصلح" البنية ولن "يُحدّثها" نيابةً عنك. هذه مهمة الترحيلات (migrations).

القيود: قواعد ملازمة لبنية الجدول

القيود (Constraints) هي الطريقة التي تنقل بها منطق التحقق إلى قاعدة البيانات نفسها. وهذه الأربعة هي الأكثر استخدامًا:

  • PRIMARY KEY — يميّز كل صف بشكل فريد. تجد تفاصيل أكثر في صفحة المفاتيح الأساسية.
  • NOT NULL — لا يُسمح بأن يكون العمود فارغًا.
  • DEFAULT value — يُستخدم عندما لا يُمرَّر العمود في عملية INSERT. يمكن أن تكون القيمة ثابتة أو تعبيرًا مثل datetime('now').
  • CHECK (expr) — يجب أن يكون التعبير صحيحًا في كل صف.
  • UNIQUE (col, col) — قيد على مستوى الجدول يفرض أن يكون مجموع القيم في الأعمدة المذكورة فريدًا.

تُطبَّق هذه القيود مع كل عملية INSERT وUPDATE. وأي صف يخالف أحدها يُرفض وتفشل العبارة بأكملها. والتقاط البيانات الخاطئة عند مستوى قاعدة البيانات أرخص بكثير من ملاحقتها بعد أن تنتشر في أرجاء التطبيق.

المفاتيح الأجنبية FOREIGN KEY في sqlite

المفتاح الأجنبي يقول ببساطة: "هذا العمود يشير إلى صف في جدول آخر". وظيفته الحفاظ على اتساق بياناتك — فلا يمكنك مثلًا الإشارة إلى مستخدم غير موجود، كما يمكن (مع الخيارات المناسبة) أن يُفضي حذف المستخدم إلى حذف طلباته معه تلقائيًا.

مَعلومة مهمة في SQLite يُفضّل حفظها: فحص المفاتيح الأجنبية مُعطَّل افتراضيًا. يجب أن تُنفّذ PRAGMA foreign_keys = ON لكل اتصال تريد منه التحقق من القيود. أغلب مُشغِّلات التطبيقات تتولّى هذا الأمر نيابةً عنك أو توفّر إعدادًا له؛ وإن لم يفعل المُشغِّل الذي تستخدمه ذلك، فنفِّذ الـ pragma فور الاتصال.

عبارة ON DELETE CASCADE هنا تعني أن حذف المستخدم سيؤدي تلقائيًا إلى حذف منشوراته. ومن الخيارات الأخرى: SET NULL، وRESTRICT، والخيار الافتراضي NO ACTION الذي يرفض عملية الحذف إذا كانت هناك سجلات تابعة.

إنشاء جدول من نتيجة استعلام باستخدام CREATE TABLE AS SELECT

أحيانًا تحتاج نسخة سريعة من نتيجة استعلام على هيئة جدول جديد — سواء للقطة بيانات، أو نسخة احتياطية، أو جدول مؤقت أثناء التحليل. هنا يأتي دور CREATE TABLE ... AS SELECT:

الجدول الجديد ينسخ أسماء الأعمدة وأنواعها (قدر الإمكان) والبيانات. لكن الأهم هو ما لا يتم نسخه: لا مفتاح أساسي، لا قيود NOT NULL، لا فهارس، ولا مفاتيح خارجية. مجرد لقطة مسطّحة للبيانات. تعامل معه كنقطة بداية لعمل سريع، لا كوسيلة لاستنساخ مخطط حقيقي.

وإذا أردت البنية فقط دون البيانات، أضف WHERE 0:

ستحصل على جدول فارغ بنفس بنية الأعمدة — مفيد لجداول الأرشفة التي ستملأها لاحقاً.

الجداول المؤقتة في sqlite

الجدول من نوع TEMP يعيش فقط طوال فترة اتصال قاعدة البيانات الحالي. بمجرد إغلاق الاتصال، يختفي الجدول تماماً — بدون أي تنظيف أو بقايا في المخطط:

استخدامات مفيدة: تجهيز صفوف لاستعلام متعدد الخطوات، أو الاحتفاظ بنتائج وسيطة معقّدة لا تصلح لـ CTE، أو عزل بيانات خاصة بكل اتصال في جلسة طويلة. كل من CREATE TEMP TABLE وCREATE TEMPORARY TABLE يؤديان الغرض نفسه.

ويمكنك أيضاً دمجها مع AS SELECT، فالصيغة CREATE TEMP TABLE snapshot AS SELECT ... نمط شائع لتجميد مجموعة نتائج في منتصف عملية تحليل.

كيفية تنسيق أسماء الأعمدة والجداول

في الغالب تكون أسماء الأعمدة والجداول مُعرِّفات مجرّدة بلا أي تنسيق خاص. أما إذا اضطُرِرت إلى استخدام كلمة محجوزة أو اسم يحتوي على مسافات، فضعه بين علامتَي اقتباس مزدوجتين (وهي الطريقة المعتمدة في معيار SQL) أو بين علامتَي backtick (وهي عادة مأخوذة من MySQL يدعمها SQLite كذلك):

يشتغل الأمر، لكنك ستعاني من هذا الاحتكاك في كل مرة تشير فيها إلى الجدول. الأفضل أن تستعمل أسماء بسيطة مثل orders وselection وuser_id، وتتخلّى عن علامات الاقتباس تمامًا.

مثال واقعي على إنشاء جدول في sqlite

لنجمع كل ما سبق في مخطط صغير لتطبيق مهام، مع استخدام IF NOT EXISTS ليعمل عند كل تشغيل دون مشاكل:

هذا مخطط جاهز للإنتاج فعليًا: إنشاء آمن قابل للتكرار، مع تفعيل المفاتيح الخارجية، وقيد CHECK يضبط قيمة done، وقيم افتراضية منطقية، وطوابع زمنية تتعبأ تلقائيًا.

الخطوة التالية: أنواع البيانات في sqlite

يسمح لك CREATE TABLE بكتابة INTEGER أو TEXT أو REAL، لكن SQLite معروفة بمرونتها الشديدة في كيفية تخزين هذه القيم فعليًا. الصفحة التالية تشرح فئات التخزين الخمس التي تستخدمها SQLite بالفعل، ولماذا قد لا يكون النوع الذي كتبته هو النوع الذي ستحصل عليه في النهاية.

الأسئلة الشائعة

كيف أُنشئ جدولًا في SQLite؟

تستخدم الصيغة CREATE TABLE name (column1 TYPE, column2 TYPE, ...)، حيث يأخذ كل عمود اسمًا ونوعًا اختياريًا، ويمكنك إضافة قيود مثل PRIMARY KEY أو NOT NULL أو DEFAULT. ينفَّذ الأمر فورًا ويُحفظ الجدول داخل ملف قاعدة البيانات.

ما فائدة IF NOT EXISTS مع CREATE TABLE؟

الصيغة CREATE TABLE IF NOT EXISTS name (...) تُنشئ الجدول فقط إذا لم يكن موجودًا بالفعل. بدونها، إعادة تشغيل السكربت على قاعدة بيانات قائمة سيُطلق خطأ table already exists. هي الحل القياسي لحماية سكربتات الترحيل (migrations) وأكواد بدء التشغيل.

هل يمكنني إنشاء جدول من استعلام SELECT في SQLite؟

نعم، الأمر CREATE TABLE new_name AS SELECT ... يُنشئ جدولًا جديدًا من نتيجة استعلام، فيُنسخ أسماء الأعمدة والبيانات. لكن انتبه: لا تُنقل القيود ولا المفاتيح الأساسية ولا الفهارس من الجدول الأصلي. استخدمه للقطات (snapshots) والجداول المؤقتة، لا كبديل عن مخطط حقيقي.

ما الفرق بين الجدول المؤقت والجدول العادي؟

الأمر CREATE TEMP TABLE (أو CREATE TEMPORARY TABLE) يُنشئ جدولًا يعيش فقط ضمن الاتصال الحالي بقاعدة البيانات ويختفي بمجرد إغلاقه، أما الجداول العادية فتُحفظ في ملف قاعدة البيانات. الجداول المؤقتة مفيدة لتخزين النتائج الوسيطة دون تلويث المخطط (schema).

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن