SQL Setup & DDL — CREATE, ALTER, DROP

SQL সেটআপ ও DDL — CREATE, ALTER, DROP

Read: ~30 min Easy 14 practice problems Live SQLite runner

1. Why DDL Comes First

Before you can store a single row of data, you must first describe the shape of that data to the database. This is the job of DDL — Data Definition Language — the subset of SQL that creates, alters and drops the structures (tables, columns, indexes) where rows eventually live. DDL is the architect's blueprint; DML (which we cover in the next module) is the bricklayer's hand.

ডেটা সংরক্ষণ করার আগে database-কে জানিয়ে দিতে হয় — সেই ডেটা দেখতে কেমন হবে। এই কাজের জন্য SQL-এর একটি অংশ আছে যাকে বলে DDL অর্থাৎ Data Definition Language। এটি দিয়ে আমরা table তৈরি করি, পরিবর্তন করি, মুছে ফেলি। DDL হলো architect-এর নকশা; পরের module-এ যে DML শিখব, সেটি হলো রাজমিস্ত্রির হাত — যা ইট গাঁথে।

By the end of this module you will be able to: open the in-browser SQLite, design a table for a real-world domain (students, orders, bKash transactions), pick the right data types, enforce business rules through PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT, CHECK and FOREIGN KEY, and modify a schema safely without losing data.

Mental model A table is just a typed spreadsheet: every column has a name, a type, and a set of rules. Once you internalise this, every SQL feature in the course becomes easier.

একটি table আসলে একটি type-যুক্ত spreadsheet — প্রতিটি column-এর একটি নাম, একটি type এবং কিছু নিয়ম থাকে। এটা মাথায় গেঁথে গেলে SQL-এর বাকি সব কিছু সহজ হয়ে যাবে।

2. The In-Browser SQLite — Zero Install

Throughout this entire course, every code block on this page runs SQLite compiled to WebAssembly — directly in your browser. There is no server, no Docker container, no apt-get install. Click Run ▶ and a fresh in-memory database is created, your SQL is executed, the result is rendered as a table, and the database is thrown away. This is identical to how the production sqlite3 command-line tool behaves with :memory:.

পুরো কোর্সে আমরা SQLite-এর একটি WebAssembly সংস্করণ ব্যবহার করব, যা সরাসরি আপনার browser-এই চলে — কোনো server, কোনো Docker, কোনো install দরকার নেই। Run ▶ চাপলেই memory-তে একটি নতুন database তৈরি হয়, আপনার SQL চলে, ফলাফল table আকারে দেখা যায়, এবং তারপর সেই database মুছে যায়। বাস্তবে sqlite3 :memory: command যেভাবে কাজ করে, এটি ঠিক সেভাবেই কাজ করে।
Browser-only SQL execution path You write SQL in this page sql-runner.js loads sql.js (WASM) SQLite engine runs in your tab Result table rendered No data ever leaves your computer — কোনো ডেটা আপনার কম্পিউটার ছেড়ে যায় না। Each Run ▶ starts a fresh in-memory database (so lessons are reproducible). Figure 11.1 — How every code block on this page works.

Try it now. The block below creates a tiny one-row table and queries it:

first_run.sql
SELECT 'Hello, Bangladesh!' AS greeting,
       2 + 2 AS arithmetic;

3. Data Types — SQLite vs PostgreSQL vs MySQL

Every column has a type — a promise about the kind of value that column will hold. The three databases you will meet most often in industry treat types slightly differently, and being aware of those differences early will save you painful migration bugs later.

প্রতিটি column-এর একটি type থাকে — অর্থাৎ সেই column-এ কী ধরনের value রাখা যাবে সেটার একটি প্রতিশ্রুতি। শিল্পক্ষেত্রে আপনারা সবচেয়ে বেশি দেখবেন SQLite, PostgreSQL এবং MySQL — এই তিনটি database। এদের type system সামান্য আলাদা; এই পার্থক্যগুলো এখনই জেনে রাখলে পরে migration-এর সময় অনেক ঝামেলা থেকে বাঁচবেন।
You want to store…SQLitePostgreSQLMySQLNotes
Whole numbersINTEGERINT / BIGINTINT / BIGINTSQLite stores as 64-bit signed.
Decimal moneyNUMERIC or REALNUMERIC(10,2)DECIMAL(10,2)Never use FLOAT/REAL for money.
Short textTEXTVARCHAR(n) / TEXTVARCHAR(n)SQLite ignores length limits.
Long text / JSONTEXTTEXT / JSONBTEXT / JSONPostgres JSONB is the industry standard.
True / FalseINTEGER (0/1)BOOLEANTINYINT(1)SQLite has no native boolean.
DateTEXT ISO-8601DATEDATESQLite recommends 'YYYY-MM-DD'.
Date + timeTEXT ISO-8601TIMESTAMPDATETIMEAlways store in UTC.
Binary blobBLOBBYTEABLOBFor files, prefer S3 + a TEXT URL.
SQLite quirk — type affinity SQLite has only five storage classes (NULL, INTEGER, REAL, TEXT, BLOB) and the type you write is treated as a hint, not a strict rule. Writing VARCHAR(20) is legal — SQLite simply maps it to TEXT and ignores the 20.

SQLite-এ মাত্র পাঁচটি storage class থাকে এবং আপনি যে type লেখেন সেটা একটি হিন্ট মাত্র, কঠোর নিয়ম নয়। তাই VARCHAR(20) লিখলেও সেটা TEXT হিসেবেই save হয় এবং দৈর্ঘ্যের সীমা প্রয়োগ হয় না।

4. CREATE TABLE — The Heart of DDL

The CREATE TABLE statement names a new table and lists its columns. Each column has a name, a type, and zero or more constraints. Constraints are non-negotiable rules that the database itself enforces — so even if your application code has a bug, the database refuses to store invalid data. This is one of the most important reasons to push business rules into the schema.

CREATE TABLE statement দিয়ে একটি নতুন table-এর নাম এবং তার column-গুলোর তালিকা দেওয়া হয়। প্রতিটি column-এর একটি নাম, একটি type এবং কিছু constraint থাকতে পারে। Constraint মানে এমন কিছু নিয়ম যা database নিজে enforce করে — application কোডে bug থাকলেও invalid ডেটা ঢুকতে পারবে না। এজন্য business rule যতটা সম্ভব database schema-তে রাখাই ভালো।

4.1 — A real schema: students at a Bangladeshi university

students_create.sql
-- Create a table for students at a university
CREATE TABLE students (
    id          INTEGER PRIMARY KEY,
    full_name   TEXT    NOT NULL,
    email       TEXT    NOT NULL UNIQUE,
    cgpa        REAL    DEFAULT 0.0,
    department  TEXT    NOT NULL DEFAULT 'CSE',
    is_active   INTEGER NOT NULL DEFAULT 1,
    enrolled_on TEXT    NOT NULL DEFAULT (date('now')),
    CHECK (cgpa >= 0.0 AND cgpa <= 4.0)
);

-- Insert two students so we can see something in the result
INSERT INTO students (full_name, email, cgpa, department)
VALUES
    ('Arif Hossain',   'arif@nsu.edu.bd',   3.85, 'CSE'),
    ('Sanjida Akter', 'sanjida@du.ac.bd',  3.92, 'EEE');

SELECT id, full_name, email, cgpa, department
FROM students;
Anatomy — line by line
PieceMeaningবাংলায়
INTEGER PRIMARY KEYUnique row id; SQLite auto-increments it.Row-এর unique পরিচয়; SQLite নিজে থেকে বাড়ায়।
NOT NULLRefuses to insert a row that leaves the column empty.Column খালি রেখে row insert করা যাবে না।
UNIQUENo two rows may share the same value.একই value দুবার থাকতে পারবে না।
DEFAULT 'CSE'If you don't specify a value, this is what the database stores.আপনি value না দিলে এটি default হিসেবে save হবে।
DEFAULT (date('now'))An expression-default — runs at insert time.Insert-এর সময় expression চালিয়ে value বসায়।
CHECK (cgpa BETWEEN 0 AND 4)Refuses any insert where the rule is violated.নিয়ম ভাঙলে database row নিতে অস্বীকার করবে।

4.2 — Constraints in action: a CHECK that rejects bad data

check_violation.sql
-- This insert has cgpa = 5.7 which violates the CHECK rule.
-- SQLite will refuse it and stop right here.
INSERT INTO students (full_name, cgpa)
VALUES ('Hacker Habib', 5.7);

You should see an error message like CHECK constraint failed — exactly what we want.

5. Foreign Keys — Linking Tables Together

A foreign key says: "the value in this column must match an existing primary-key value in another table." This is what turns a pile of tables into a relational database. Without foreign keys you can have an orders row referring to a customer_id that does not exist — an orphan record — and your reports start lying.

Foreign key বলতে বোঝায় — এই column-এর value অন্য একটি table-এর primary key-তে অবশ্যই থাকতে হবে। এই rule-ই কয়েকটি আলাদা table-কে একটি সত্যিকারের relational database বানায়। এটি না থাকলে এমন order তৈরি হতে পারে, যার customer-ই অস্তিত্বে নেই — সেগুলো orphan record বলে এবং report-এ ভুল তথ্য দেখায়।
fk_demo.sql
-- Enable FK enforcement (SQLite turns it off by default for legacy reasons)
PRAGMA foreign_keys = ON;

CREATE TABLE customers (
    id    INTEGER PRIMARY KEY,
    name  TEXT    NOT NULL,
    phone TEXT    UNIQUE
);

CREATE TABLE orders (
    id          INTEGER PRIMARY KEY,
    customer_id INTEGER NOT NULL,
    amount      NUMERIC NOT NULL CHECK(amount > 0),
    placed_on   TEXT    DEFAULT (datetime('now')),
    FOREIGN KEY (customer_id) REFERENCES customers(id)
        ON DELETE RESTRICT ON UPDATE CASCADE
);

INSERT INTO customers(name, phone) VALUES
    ('Rahim Uddin',  '01711-100100'),
    ('Karim Mia',    '01911-200200');

INSERT INTO orders(customer_id, amount) VALUES
    (1, 1499.50),
    (2,  320.00);

SELECT o.id, c.name, o.amount
FROM orders o
JOIN customers c ON c.id = o.customer_id;
Action clauseWhat happensবাংলায়
ON DELETE RESTRICTRefuses to delete a parent that still has children.Child থাকলে parent মুছে ফেলা যাবে না।
ON DELETE CASCADEDeletes children automatically with the parent.Parent মুছলে child-ও স্বয়ংক্রিয়ভাবে মুছে যাবে।
ON DELETE SET NULLSets the FK column to NULL when the parent dies.Parent মুছলে FK column NULL হয়ে যাবে।
ON UPDATE CASCADEPropagates a parent-id change to all children.Parent-এর id পরিবর্তন হলে সেটি child-এও বসবে।

6. ALTER TABLE — Evolving the Schema

Real applications evolve. New requirements arrive, columns get renamed, new fields are added. ALTER TABLE lets you change a table's structure without dropping its data. SQLite supports four flavours: add column, rename column, rename table, and drop column (since 3.35).

বাস্তব application-এর schema সময়ের সাথে পরিবর্তন হয় — নতুন column যুক্ত করা, পুরোনো column-এর নাম বদলানো ইত্যাদি। ALTER TABLE দিয়ে ডেটা না হারিয়ে এই পরিবর্তনগুলো করা যায়। SQLite-এ চারটি প্রধান অপারেশন আছে — column যোগ, column-এর নাম পরিবর্তন, table-এর নাম পরিবর্তন এবং column drop (৩.৩৫ সংস্করণ থেকে)।
alter_demo.sql
-- 1) Add a new column with a sensible default
ALTER TABLE products ADD COLUMN stock INTEGER NOT NULL DEFAULT 0;

-- 2) Rename a column (better naming = clearer code)
ALTER TABLE products RENAME COLUMN name TO title;

-- 3) Rename the table itself
ALTER TABLE products RENAME TO catalog_items;

-- 4) Verify the new shape
SELECT * FROM catalog_items;
What SQLite cannot do directly SQLite cannot, in a single statement, change a column's type, drop a constraint, or reorder columns. The standard workaround is the "copy table" dance:
  1. CREATE TABLE products_new (...) with the new shape.
  2. INSERT INTO products_new SELECT … FROM products.
  3. DROP TABLE products.
  4. ALTER TABLE products_new RENAME TO products.
PostgreSQL and MySQL handle these in one statement; SQLite trades that ability for a tiny binary.

একই statement দিয়ে SQLite-এ column-এর type পরিবর্তন বা constraint drop করা যায় না। সমাধান হলো — নতুন shape-এ একটি table বানিয়ে, পুরনো ডেটা copy করে, পুরনো table drop করে, নতুনটিকে rename করা।

7. DROP TABLE vs TRUNCATE vs DELETE

Three different statements can "remove" things, and confusing them is one of the most expensive mistakes a junior engineer can make. The table below makes the differences crystal clear.

StatementRemoves…Keeps schema?Triggers fire?Reversible inside a transaction?
DELETE FROM t;All rows (one by one)YesYesYes (ROLLBACK works)
DELETE FROM t WHERE …;Matching rows onlyYesYesYes
TRUNCATE TABLE t; (Postgres / MySQL)All rows (fast, set-based)YesOften skippedPostgres: yes · MySQL: usually no
DROP TABLE t;The whole table — schema and dataNo — table ceases to existn/aYes (Postgres) · Yes (SQLite, inside a tx)
DELETE row মুছে কিন্তু table-এর গঠন রাখে এবং transaction-এর ভেতরে rollback করা যায়। TRUNCATE দ্রুত সব row মুছে দেয় কিন্তু MySQL-এ rollback সম্ভব নয়। DROP TABLE পুরো table-ই মুছে দেয় — schema এবং ডেটা দুটোই। এই তিনটিকে এক করে ফেললে production-এ বিপদ — তাই খুব ভালোভাবে চিনে রাখা জরুরি।

SQLite does not have TRUNCATE, but it optimises DELETE FROM t (without a WHERE) into a fast O(1) operation internally — called the "truncate optimization":

delete_vs_drop.sql
SELECT COUNT(*) AS before_delete FROM bkash_tx;

-- Wipe all rows (schema preserved)
DELETE FROM bkash_tx;

SELECT COUNT(*) AS after_delete FROM bkash_tx;

-- Schema still exists — we can insert again
INSERT INTO bkash_tx(sender, amount) VALUES ('01911-999999', 9999);

SELECT * FROM bkash_tx;
Production safety Never type DROP TABLE or DELETE FROM directly into a production console. Wrap destructive statements in a transaction, run a SELECT first to confirm the row count, and only then commit. We will revisit this in Module 12.

Production-এ সরাসরি DROP TABLE বা WHERE-হীন DELETE চালানো অত্যন্ত বিপজ্জনক। আগে SELECT COUNT(*) দিয়ে যাচাই করুন, transaction-এ মোড়ান, তারপর commit করুন।

8. Quick Reference — Constraints That Save Lives

✅ Always set (সবসময় দিন)

  • PRIMARY KEY — every table needs one identity column.
  • NOT NULL on columns the business cannot live without.
  • UNIQUE on natural keys (email, phone, NID).
  • FOREIGN KEY on every "id-of-another-table" column.
  • DEFAULT for created_at, status, currency.

⚠️ Common mistakes (সাধারণ ভুল)

  • Storing money in FLOAT / REAL.
  • Storing dates as "12/03/2024" — pick ISO-8601.
  • Forgetting PRAGMA foreign_keys = ON in SQLite.
  • Using VARCHAR(20) in SQLite expecting it to truncate.
  • Dropping a table when you only meant to delete its rows.

9. Practice Problems

Each problem has a Show Answer button. Most answers are runnable — click Run to see the result on the spot. Solve it yourself first, then check.

প্রতিটি প্রশ্নের সাথে Show Answer বাটন আছে। বেশিরভাগ উত্তর সরাসরি এই পেজে চালানো যাবে — প্রথমে নিজে চেষ্টা করুন, পরে উত্তর মিলিয়ে নিন।
  1. Create a table teachers with columns id (PK), name (NOT NULL), email (UNIQUE), salary (positive only). Insert two rows and select them.
    একটি teachers table বানান যাতে id, name, email এবং salary থাকবে; দুটি row insert করে দেখান।
    ✨ Show Answer (উত্তর দেখুন)
    ans1.sql
    CREATE TABLE teachers (
        id     INTEGER PRIMARY KEY,
        name   TEXT    NOT NULL,
        email  TEXT    UNIQUE,
        salary NUMERIC CHECK (salary > 0)
    );
    INSERT INTO teachers(name, email, salary) VALUES
        ('Prof. Jamilur Rahman', 'jamil@buet.ac.bd', 85000),
        ('Dr. Tania Ahmed',     'tania@du.ac.bd',   92000);
    SELECT * FROM teachers;
  2. Add a phone column (TEXT, UNIQUE) to an existing customers table.
    বিদ্যমান customers table-এ একটি phone column যোগ করুন।
    ✨ Show Answer
    ans2.sql
    ALTER TABLE customers ADD COLUMN phone TEXT UNIQUE;
    UPDATE customers SET phone = '01711-000001' WHERE id = 1;
    UPDATE customers SET phone = '01711-000002' WHERE id = 2;
    SELECT * FROM customers;
  3. Rename the column name in customers to full_name.
    customers table-এ name column-এর নাম বদলে full_name করুন।
    ✨ Show Answer
    ans3.sql
    ALTER TABLE customers RENAME COLUMN name TO full_name;
    SELECT * FROM customers;
  4. Create a table library_books where isbn is the primary key and copies defaults to 1.
    একটি library_books table বানান, যেখানে isbn primary key এবং copies এর default value ১।
    ✨ Show Answer
    ans4.sql
    CREATE TABLE library_books (
        isbn   TEXT    PRIMARY KEY,
        title  TEXT    NOT NULL,
        author TEXT    NOT NULL,
        copies INTEGER NOT NULL DEFAULT 1 CHECK(copies >= 0)
    );
    INSERT INTO library_books(isbn, title, author) VALUES
        ('978-984-401-001-1', 'Pother Pachali', 'Bibhutibhushan');
    SELECT * FROM library_books;
  5. Drop the teachers table if it exists, then verify it is gone using sqlite_master.
    teachers table-টি drop করুন এবং পরে sqlite_master দিয়ে যাচাই করুন।
    ✨ Show Answer
    ans5.sql
    DROP TABLE IF EXISTS teachers;
    SELECT name FROM sqlite_master WHERE type = 'table';
  6. Design two related tables departments and employees with a foreign key from employee to department.
    দুটি সম্পর্কিত table — departments এবং employees — foreign key সহ ডিজাইন করুন।
    ✨ Show Answer
    ans6.sql
    PRAGMA foreign_keys = ON;
    
    CREATE TABLE departments (
        id   INTEGER PRIMARY KEY,
        name TEXT NOT NULL UNIQUE
    );
    
    CREATE TABLE employees (
        id            INTEGER PRIMARY KEY,
        name          TEXT NOT NULL,
        department_id INTEGER NOT NULL,
        FOREIGN KEY (department_id) REFERENCES departments(id)
    );
    
    INSERT INTO departments(name) VALUES ('Engineering'), ('Finance');
    INSERT INTO employees(name, department_id) VALUES
        ('Mahmud', 1), ('Sabina', 2);
    
    SELECT e.name, d.name AS department
    FROM employees e JOIN departments d ON d.id = e.department_id;
  7. Why does SQLite store dates as TEXT rather than DATE? Answer in two sentences.
    SQLite কেন date-কে TEXT হিসেবে রাখে, DATE নয়? দুই বাক্যে ব্যাখ্যা করুন।
    ✨ Show Answer

    Answer: SQLite was designed as an extremely small embedded engine with only five storage classes (NULL, INTEGER, REAL, TEXT, BLOB) and no native date type. Storing dates as ISO-8601 TEXT ('YYYY-MM-DD HH:MM:SS') keeps the engine tiny while still allowing correct lexicographic ordering and the full date() / strftime() function family.

    SQLite-কে অত্যন্ত ছোট embedded engine হিসেবে ডিজাইন করা হয়েছে; এতে মাত্র পাঁচটি storage class আছে এবং কোনো native date type নেই। ISO-8601 ফরম্যাটে TEXT হিসেবে date রাখলেই engine ছোট থাকে, lexicographic sort ঠিকঠাক কাজ করে এবং date()/strftime() ফাংশনগুলোও ব্যবহার করা যায়।

  8. Add a CHECK constraint to ensure mobile-recharge amount is between 10 and 5000 BDT.
    Mobile recharge amount ১০ থেকে ৫০০০ টাকার মধ্যে আছে কিনা যাচাইয়ের জন্য CHECK যোগ করুন।
    ✨ Show Answer
    ans8.sql
    CREATE TABLE recharges (
        id     INTEGER PRIMARY KEY,
        phone  TEXT    NOT NULL,
        amount NUMERIC NOT NULL CHECK(amount BETWEEN 10 AND 5000)
    );
    INSERT INTO recharges(phone, amount) VALUES
        ('01911-111111', 50),
        ('01911-222222', 1000);
    SELECT * FROM recharges;
  9. Use CREATE TABLE IF NOT EXISTS to make a "first run safe" creation script.
    CREATE TABLE IF NOT EXISTS দিয়ে এমন script লিখুন যা প্রথম এবং পরবর্তী রান উভয়েই কাজ করবে।
    ✨ Show Answer
    ans9.sql
    CREATE TABLE IF NOT EXISTS notes (
        id      INTEGER PRIMARY KEY,
        body    TEXT    NOT NULL,
        created TEXT    DEFAULT (datetime('now'))
    );
    -- Running this twice is harmless; the second time is a no-op.
    CREATE TABLE IF NOT EXISTS notes (
        id INTEGER PRIMARY KEY, body TEXT
    );
    SELECT name FROM sqlite_master WHERE type = 'table';
  10. Create a composite primary key (course_id, student_id) for an enrollments table.
    একটি enrollments table-এ (course_id, student_id) — composite primary key দিন।
    ✨ Show Answer
    ans10.sql
    CREATE TABLE enrollments (
        course_id  INTEGER NOT NULL,
        student_id INTEGER NOT NULL,
        grade      TEXT,
        PRIMARY KEY (course_id, student_id)
    );
    INSERT INTO enrollments VALUES (101, 1, 'A'), (101, 2, 'B+');
    SELECT * FROM enrollments;
  11. Make a products table where price must be greater than zero and stock non-negative.
    এমন products table বানান যেখানে price ০-এর বেশি ও stock non-negative।
    ✨ Show Answer
    ans11.sql
    CREATE TABLE products (
        id    INTEGER PRIMARY KEY,
        title TEXT    NOT NULL,
        price NUMERIC NOT NULL CHECK(price > 0),
        stock INTEGER NOT NULL DEFAULT 0 CHECK(stock >= 0)
    );
    INSERT INTO products(title, price, stock) VALUES
        ('Walton fan', 3500, 12),
        ('Pran juice 1L', 95, 200);
    SELECT * FROM products;
  12. List the difference between DELETE and DROP in three short bullet points.
    তিনটি ছোট bullet-এ DELETE এবং DROP-এর পার্থক্য লিখুন।
    ✨ Show Answer
    • DELETE removes rows; the table and its schema remain.
    • DROP removes the entire table — schema, indexes, triggers, everything.
    • DELETE can be filtered by WHERE; DROP cannot.

    DELETE শুধু row মুছে; DROP পুরো table মুছে দেয়।

  13. In one statement, drop a column from an existing SQLite table (3.35+).
    SQLite ৩.৩৫+ ব্যবহার করে এক statement-এ একটি column drop করুন।
    ✨ Show Answer
    ans13.sql
    ALTER TABLE temp_t DROP COLUMN b;
    SELECT * FROM temp_t;
  14. Why is putting NOT NULL on a column "free protection"? Explain in 2 sentences.
    কেন একটি column-এ NOT NULL দেওয়া "ফ্রি সুরক্ষা"? দুই বাক্যে ব্যাখ্যা করুন।
    ✨ Show Answer

    Answer: A NULL value silently disables many query semantics — comparisons return UNKNOWN, aggregates skip the row, and joins behave unexpectedly. Forbidding NULLs at the database level eliminates an entire class of bugs that the application would otherwise have to handle case by case.

    NULL value-এর কারণে অনেক query চুপচাপ ভুল ফল দেয় — তুলনা UNKNOWN হয়, aggregate row বাদ দেয়, join-এর আচরণ বদলায়। তাই database-এই NULL forbid করলে অনেক bug-ই আগে থেকে আটকে যায়।

Summary — Module 11

DDL defines the shape of a database: CREATE TABLE brings tables into existence, ALTER TABLE evolves them, DROP TABLE removes them. Every column has a type and zero or more constraints (PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT, CHECK, FOREIGN KEY) — push your business rules here so the database itself enforces them. SQLite has only five storage classes and treats type declarations as hints, while PostgreSQL and MySQL are strict — keep the table from §3 nearby until the differences feel natural.

DDL দিয়ে database-এর গঠন ঠিক করা হয় — CREATE দিয়ে table তৈরি, ALTER দিয়ে পরিবর্তন, DROP দিয়ে মুছে ফেলা। প্রতিটি column-এর type এবং কিছু constraint (PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT, CHECK, FOREIGN KEY) থাকে — business rule যতটা সম্ভব এখানেই রাখুন। SQLite-এর type system নরম, কিন্তু PostgreSQL এবং MySQL কঠোর — পার্থক্যগুলো মনে রাখা জরুরি।

Next Module → DML I — INSERT, UPDATE, DELETE। ডেটা সংরক্ষণ, পরিবর্তন এবং নিরাপদে মুছে ফেলার কৌশল।