درس php

مفهوم – درس php عن طريقة إنشاء جداول قاعدة البيانات.

أولاً : إنشاء جداول قاعدة البيانات :

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

وكما ترى ، لقد قمت بالتركيز على كلمات معينة لتمثل أسماء الجداول في قاعدة البيانات التي نريدها .

المستخدمون users

التصنيفات categories

المواضيع topics

التعليقات replies

العناصر الثلاثة الأخيرة مرتبطة ببعضها البعض ، لذا سنقوم بعمل ذلك في تصميم الجدول .

يمكن إنشاء قاعدة بيانات MySQL باستخدام أوامر Sql ، ولكننا هنا سنستخدم برنامج بواجهة رسومية ليسهل العملية ويجعلها مفهومة أكثر ، وممتعة أكثر . البرنامج هو Workbench ، يمكنك التعرف عليه أكثر من خلال هذه المشاركة ، ولكن ذلك غير مطلوب لفهم تكملة هذا الشرح.

كيفية عمل منتدى باستخدام php و MySQL من الصفر

يبدو مرتباً أليس كذلك ؟ كل مربع هو عبارة عن جدول في قاعدة البيانات . جميع الأعمدة مدونة داخل كل جدول .. والخطوط بين الجداول تمثل العلاقة بينهم . سوف نشرح ذلك لاحقاً ، لا بأس إن لم تفهم الكثير الآن ..

سوف نناقش كل جدول بشرح أوامر Sql . والتي تم إنشاءها تلقائياً مع إنشاء المخطط في الأعلى . لصنع كودك الخاص يمكنك إنشاء مخطط مشابه وستحصل على أوامر الـ Sql التي قامت بإنشاء المخطط أيضاً . بعض محررات قواعد البيانات مثل MySQL Workbench الذي قمنا بإستخدامه لإنتاج ذلك المخطط ينتج ملفات بلاحقة Sql أيضاً . ولكننا ننصح تعلم أوامر Sql حيث ستجد الأمر ممتعاً . لمقدمة حول Sql يمكنك قراءة المشاركة هنا.

جدول المستخدمين
CREATE TABLE users (
user_id
INT(8) NOT NULL AUTO_INCREMENT,
user_name
VARCHAR (30) NOT NULL,
user_pass
VARCHAR (255) NOT NULL,
user_email VARCHAR (255) NOT NULL,
user_date
DATETIME NOT NULL,
user_level INT(8) NOT NULL,
UNIQUE INDEX user_name_unique (user_name),
PRIMARY KEY (user_id)
) TYPE=INNODB;
تحديث: في بعض إصدارات mysql قد يحدث خطأ عند كتابة الأمر أعلاه وكذلك أوامر sql في الأسفل، إذا حصلت على رسالة خطأ فقم دائماً باستبدال السطر الأخير TYPE=INNODB بـ Engine=InnoDB

تستخدم عبار CREATE TABLE لإنشاء جدول جديد. يتبع هذه العبارة اسم الجدول المراد إنشاؤه، ويتم وضع جميع أعمدة الجدول بين قوسين. بالنسبة لأسماء الحقول فهي تشرح نفسها بنفسها، لذا سنناقش الآن أنواع البيانات فقط.

user_id
مفتاح أولي يستخدم لتعريف كل عمود في الجدول بشكل فريد (غير قابل للتكرار). نوع هذا الحقل هو INT، وهذا يعني أن الحقل يجب أن يحوي على عدد صحيح (غير عشري). ولا يمكن لهذا الحقل أن يكون فارغاً بما أننا استخدمنا عبارة (NOT NULL). يمكن أن ترى في أسفل الجدول أن حقل user_id تم تحديده على أنه مفتاح أولي (primary key). يستخدم المفتاح الأولي كما ذكرنا لتعريف كل عمود في الجدول بشكل فريد،أي لا يمكن لأي عمودين في الجدول أن يكون لهم نفس القيمة لهذا الحقل. الكلام غير واضح؟ بالمثال يزول الإشكال :

لدينا مستخدم على سبيل المثال يدعى أحمد، إذا قام مستخدم آخر بالتسجيل وبنفس الاسم، فسيكون هناك مشكلة. ﻷنه لا يمكن التفريق بين أحمد هذا وأحمد ذاك. لا يمكنك التفريق ولا يمكن حتى لقاعدة البيانات حينها التفريق بينهم. يتم حل هذه المشكلة باستخدام المتاح الأولي (primary key) ، حيث سيعطى للاسمين رقم مختلف.

جميع الجداول الأخرى تحوي على مفاتيح أولية وتعمل بنفس الطريقة.

user_name
هذا حقل نصي (وليس رقمي كالحقل السابق). يدعي الحقل بلغة SQL حقل VARCHAR وهو أحد أنواع الحقول النصية. الرقم بين الأقواس هو أقصى طول لعدد الأحرف التي يمكن أن يتم إدخالها في الحقل. في حالتنا هذه يمكن للمستخدم اختيار اسم يبلغ طوله كحد أقصى 30 حرف. ولا يمكن لهذا الحقل أن يكون فارغاً (NOT NULL)، سترى أسفل الجدول أن هذا الحقل تم تحديده على أنه فريد (UNIQUE)، وهذا يعني أنه لا يمكن لشخصين التسجيل بنفس الاسم.

الجزء الذي يحوي على عبارة UNIQUE INDEX يُخبر قاعدة البيانات أننا نريد إضافة مفتاح فريد (UNIQUE KEY)، بعدها قمنا بتحديد اسم المفتاح الفريد وهو هنا user_name_unique ، وبين الأقواس اسم الحقل الذي سينطبق المفتاح الفريد عليه (ليصبح غير قابل لتكرار قيمته مرتين في الجدول).

user_pass
هذا الحقل نفس الحقل السابق، باستثناء الطول الأقصى له ، فبما أن كلمة سر المستخدم ومهما كان طولها سيتم تشفيرها لنوع تشفير sha1 ، فكلمة السر ستكون دائماً مع نوع التشفير هذا بطول 40 حرف.

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

user_email
هذا الحقل هو تماماً نفس الحقل السابق (بالنسبة لقاعدة البيانات، أما لاحقاً عند عمل نموذج دخول بلغة HTML فيختلف الموضوع قليلاً )

user_date
في هذا الحقل يتم تخزين التاريخ الذي قام به المستخدم بالتسجيل. نوع هذا الحقل هو DATETIME ولا يمكن أن يكون فارغ. (يتم تعبئة الحقل تلقائياً بحسب توقيت السيرفر).

user_level
يحوي هذا الحقل مستوى المستخدم، على سبيل المثال: 0 للمستخدم العادي و 1 للمدير. ستتعرف على المزيد لاحقاً.

جدول التصنيفات
CREATE TABLE categories (
cat_id
INT(8) NOT NULL AUTO_INCREMENT,
cat_name
VARCHAR (255) NOT NULL,
cat_description
VARCHAR(255) NOT NULL,
UNIQUE INDEX cat_name_unique (cat_name),
PRIMARY KEY (cat_id)
) TYPE=INNODB
أنواع البيانات هنا تعمل بشكل أساسي بنفس الطريقة التي تعمل بها أنواع البيانات في جدول المستخدمين. يحوي هذا الجدول أيضاً مفتاح أولي ، واسم التصنيف يجب أن يكون فريد .

جدول المواضيع
CREATE TABLE topics (
topic_id
INT(8) NOT NULL AUTO_INCREMENT,
topic_subject
VARCHAR(255) NOT NULL,
topic_date
DATETIME NOT NULL,
topic_cat
INT(8) NOT NULL,
topic_by
INT(8) NOT NULL,
PRIMARY KEY (topic_id)
) TYPE=INNODB;
هذا الجدول تقريباً نفس الجداول السابقة، باستثناء حقل topic_by والذي يشير للمستخدم المنشئ للموضوع. وحقل topic_cat الذي يشير للتصنيف الذي يتبع الموضوع له. لا يمكن تحديد العلاقات بين هذه الحقول بذكر أسماء الحقول فقط. فيجب أن نُعلم قاعدة البيانات أن هذا الحقل (topic_by) يجب أن يحتوي على الرقم التسلسلي user_id لمستخدم موجود في جدول المستخدمين، والحقل الآخر (topic_cat) يجب أن يحتوي على الرقم التسلسلي cat_id لتصنيف موجود في جدول التصنيفات. سنضيف هذه العلاقات بين الحقول والجداول بعد مناقشة جدول التعليقات.

جدول التعليقات
CREATE TABLE posts (
post_id
INT(8) NOT NULL AUTO_INCREMENT,
post_content
TEXT NOT NULL,
post_date
DATETIME NOT NULL,
post_topic
INT(8) NOT NULL,
post_by
INT(8) NOT NULL,
PRIMARY KEY (post_id)
) TYPE=INNODB;
هذا الجدول هو نفس بقية الجداول، ويوجد هنا أيضاً حقل يشير لرقم مستخدم user_id في جدول المستخدمين : حقل post_by ، حقل post_topic يشير للموضوع الذي يتبع التعليق له .

المفتاح الخارجي foreign key هو قيد مرجعي بين جدولين. يُعرِّف المفتاح الخارجي عمود أو مجموعة أعمدة في جدول (مرجعي) والذي يشير لعمود أو مجموعة أعمدة في جدول (مرجعي) آخر .

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

العمود في الجدول المرجعي والذي يشير له المفتاح الخارجي يجب أن يكون مفتاح أولي.

القيم المشار لها يجب أن تكون موجودة في الجدول المرجعي.

أعرف أن كل هذه المصطلحات جديدة عليك، ولكنك ستكتشف أنها بسيطة جداً، هي فقط علاقة بين جدول وآخر ، ستتضح لك الأمور في السطور القادمة.

بإضافة مفاتيح خارجية تصبح المعلومات مرتبطة ببعضها، وهذا مهم جداً في ترتيب قاعدة البيانات.

الآن أصبحت تعرف نوعاً ما ما هو المفتاح الخارجي ولماذا نستخدمه. حان الوقت لإضافة مفاتيح خارجية للجداول التي أنشأناها باستخدام عبارة ALTER، والتي تستخدم لتعديل جدول موجود مسبقاً.

سنقوم في البداية بربط المواضيع بالتصنيفات:

ALTER TABLE topics ADD FOREIGN KEY(topic_cat) REFERENCES categories(cat_id) ON DELETE CASCADE ON UPDATE CASCADE;
الجزء الأخير من التعليمة يوضح ما يجري. فعندما يتم حذف التصنيف من قاعدة البيانات، جميع المواضيع المرتبطة بهذا التصنيف سيتم حذفها أيضاً. إذا تم تغيير قيمة cat_id لتصنيف ما، جميع المواضيع المرتبطة بهذا التصنيف سيتم تحديثها أيضاً. وهذا ما تقوم به عبارة ON UPDATE CASCADE . بالطبع يمكنك التراجع عن ذلك لحماية بياناتك، وذلك بجعل حذف تنصيف ما غير ممكن ما زال هناك مواضيع مرتبطة بهذا التصنيف، إذا أردت القيام بذلك، فعليك استبدال ON DELETE CASCADE إلى ON DELETE RESTRICT . يوجد أيضاً عبارات SET NULL أي اجعله فارغاً و NO ACTION أي لا تقم بأي إجراء.

الآن، كل موضوع أصبح مرتبط بتصنيف ما. لنقم بربط المواضيع بالمستخدمين المنشئين لهم.

ALTER TABLE topics ADD FOREIGN KEY(topic_by) REFERENCES users(user_id) ON DELETE RESTRICT ON UPDATE CASCADE;
المفتاح الخارجي هنا هو نفسه كسابقه، ولكن هناك فرق واحد: لا يمكن حذف المستخدم ما زال هناك مواضيع مرتبطة به، أو بالأحرى مرتبطة بـ user_id للمستخدم (رقمه التسلسلي في قاعدة البيانات). لم نضع هنا ON DELETE CASCADE ﻷننا لا نريد للمعلومات المرتبطة بحساب ما والتي قد تكون قيمة أن تُحذف عندما يقرر المستخدم حذف حسابه. لإبقاء خيار حذف الحساب متاحاً للمستخدمين، يجب أن تقوم بإنشاء ميزة تنقل المواضيع لحساب “مجهول” عند حذف مستخدم لحسابه. وفي الواقع هذا ليش موضوع نقاشنا في هذا الشرح.

ربط التعليقات بالمواضيع:

ALTER TABLE posts ADD FOREIGN KEY(post_topic) REFERENCES topics(topic_id) ON DELETE CASCADE ON UPDATE CASCADE;
وأخيراً، ربط كل تعليق بالمستخدم المنشئ له:

ALTER TABLE posts ADD FOREIGN KEY(post_by) REFERENCES users(user_id) ON DELETE RESTRICT ON UPDATE CASCADE;
انتهى الجزء الخاص بقاعدة البيانات! لقد كان عملاً متعباً نوعاً ما، ولكن النتيجة تستحق هذا العمل، حيث حصلنا على قاعدة بيانات نموذجبة.

شاركها

اترك تعليقاً