Lesson 9 / الدرس 9

Designing a table / تصميم جدول

Choosing the columns, their types and their names. These decisions are cheap on the first day and expensive on every day after, because changing a column means changing every row and every query that mentions it.

اختيار الأعمدة وأنواعها وأسمائها. وهذه قرارات رخيصة في اليوم الأول وغالية في كل يوم بعده، لأن تغيير عمود يعني تغيير كل صف وكل استعلام يذكره.

One fact per column

CREATE TABLE guests (
  id     INT AUTO_INCREMENT PRIMARY KEY,
  name   VARCHAR(120) NOT NULL,
  city   VARCHAR(60),
  email  VARCHAR(160) NOT NULL UNIQUE,
  phone  VARCHAR(20)
);
The demonstration builds the same guest list twice — once with everything crammed into one text column, once split properly — and then asks each of them the same three questions. The badly designed one can answer none of them without string surgery.

The LIKE '%Cairo%' query works, and that is the trap. It also matches a guest whose street is Cairo Road and one whose email is me@cairo.com; it cannot count guests per city, cannot sort by city, cannot find the guests with no phone, and gets slower with every row because there is nothing to index. One column holding four facts is not a shortcut — it is four columns you will have to extract later, from data that has drifted into three different formats by then.

Types, and the ones that bite

ForUseNot
A short name or emailVARCHAR(n)TEXT — it cannot be indexed as easily
MoneyDECIMAL(10,2)FLOAT — 0.1 + 0.2 is not 0.3
A count or an idINTVARCHAR — sorting gives 1, 10, 2
A dateDATE or DATETIMEVARCHAR — no comparison, no arithmetic
Yes or noTINYINT(1) / BOOLEANVARCHAR holding 'yes' and 'Y' and '1'
A fixed set of statesVARCHAR with a check, or ENUMFree text nobody spells the same twice

The money row is not pedantry. FLOAT stores a very close approximation, and invoices that are one piastre out on a thousandth of a row are a real support ticket. Store money as DECIMAL, or as an integer number of piastres, and never as a float.

Four naming habits, worth adopting on day one because renaming later touches every query in the project. Table names plural and lower case: guests, not Guest or tbl_guest. The primary key called id in every table, so you never have to look it up. A foreign key named <table>_id — guest_id — so its meaning is visible without a diagram. And no prefixes repeating the table name: guests.name, never guests.guest_name, which reads as a stammer in every join you will ever write.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. Why is one column holding "name, city, email, phone" a bad idea?

2. Which type should hold money?

3. What does the practice engine NOT do that MySQL does?

Your task / مهمتك

Design the tables for a small system of your choosing — not a hotel. Write the CREATE TABLE statements out in full, with a type for every column, NOT NULL where a value is always present, and a note beside each nullable column saying exactly what its NULL means. Then run them on your own MySQL, and deliberately break three rules — text into an integer, a duplicate in a unique column, a missing required value — and record the exact message each time. Bring the three messages back here with your schema.

صمّم جداول نظام صغير من اختيارك — لا فندقًا. واكتب جمل CREATE TABLE كاملة، بنوع لكل عمود، وNOT NULL حيث تكون القيمة موجودة دائمًا، وملاحظة بجانب كل عمود يقبل العدم تقول بالضبط ما يعنيه NULL فيه. ثم شغّلها على MySQL عندك، واكسر ثلاث قواعد عمدًا — نص في عدد صحيح، وتكرار في عمود فريد، وقيمة مطلوبة ناقصة — وسجّل الرسالة بنصها كل مرة. وأحضر الرسائل الثلاث معك هنا مع مخططك.

  • Full CREATE TABLE statements with types جمل CREATE TABLE كاملة بالأنواع
  • Every nullable column explained كل عمود يقبل العدم مشروح
  • Three constraint violations attempted on real MySQL ثلاث مخالفات قيود على MySQL حقيقية
  • The three exact error messages recorded رسائل الخطأ الثلاث بنصها مسجَّلة
How do you want to submit? / كيف تريد التسليم؟