Chapter 6: PostgreSQL Create Table

1. What does CREATE TABLE actually do? (Honest teacher explanation)

CREATE TABLE tells PostgreSQL: “Hey, make me a new, initially empty table inside the current database. Give it this name, these columns with these data types, and enforce these rules so the data stays clean and consistent.”

  • The table starts empty (zero rows).
  • You define columns (like fields in a form) and their types (text? number? date?).
  • You add rules/constraints (no duplicates, must fill this field, this value links to another table…).
  • PostgreSQL automatically creates supporting objects (indexes for PRIMARY KEY / UNIQUE, sequences for SERIAL/IDENTITY…).

After running it → the table exists forever (until you DROP it), and you can INSERT rows into it.

2. Basic syntax skeleton (the core shape you’ll see 90% of the time)

SQL
  • table_name → lowercase_with_underscores is PostgreSQL convention (case-sensitive but folds to lower unless quoted).
  • Columns listed inside parentheses, separated by commas.
  • Ends with semicolon ;

3. Step-by-step real example – building a “students” table (like a real college app)

Connect to your database first (in psql or pgAdmin):

SQL

Now let’s create a proper students table:

SQL

Run this → you get: CREATE TABLE

What just happened?

  • BIGSERIAL = auto-incrementing 64-bit integer (best modern choice over SERIAL)
  • PRIMARY KEY = unique + not null + auto-index
  • NOT NULL = must have value
  • UNIQUE = no duplicates allowed (email & roll_number)
  • CHECK = custom business rule (valid year, semester range, gpa bounds)
  • DEFAULT = auto-fill if you don’t provide value
  • GENERATED ALWAYS AS … STORED = computed column (full_name auto-built, stored on disk)
  • TIMESTAMP WITH TIME ZONE = proper time with timezone awareness (Hyderabad = IST)
  • JSONB = store flexible structured data (e.g. {“city”: “Hyderabad”, “pin”: “500081”})

4. Common column data types you’ll use every day (2026 favorites)

Type Use case example Size / Notes
BIGSERIAL / BIGINT GENERATED ALWAYS AS IDENTITY Primary keys, auto-increment 64-bit, up to ~9 quintillion
VARCHAR(n) / TEXT Names, emails, descriptions TEXT = unlimited, preferred over VARCHAR without limit
NUMERIC(precision, scale) Money, GPA, measurements (exact) No rounding errors
INTEGER / SMALLINT Counts, years, semesters 32-bit / 16-bit
BOOLEAN Flags (is_active, is_verified) True/False
DATE / TIMESTAMP WITH TIME ZONE Birthdays, created_at timestamptz = best for global apps
JSONB Profiles, settings, metadata Indexed, queryable like document DB
UUID External IDs (from frontend) gen_random_uuid() default
BYTEA Images/files (small ones) Usually better in S3 + path in DB

5. Adding relationships – Foreign Key example

Let’s create a related courses and enrollments table:

SQL
  • REFERENCES students(id) = foreign key → must point to existing student
  • ON DELETE CASCADE = if student deleted → auto-remove their enrollments
  • Multi-column UNIQUE = table-level constraint

6. Quick cheatsheet – most useful constraints

What you want How to write it Where
Must fill value NOT NULL Column
No duplicates UNIQUE Column or table
Unique + not null + index PRIMARY KEY Column or table
Valid range CHECK (gpa BETWEEN 0 AND 10) Column or table
Auto-increment ID BIGSERIAL PRIMARY KEY or BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY Column
Default value DEFAULT CURRENT_TIMESTAMP Column
Computed column full_name TEXT GENERATED ALWAYS AS (…) STORED Column
Link to another table FOREIGN KEY … REFERENCES … Column or table

7. After CREATE TABLE – verify it worked (in psql or pgAdmin)

SQL

In pgAdmin: expand database → Schemas → public → Tables → right-click students → Properties

8. Common beginner mistakes & tips (from real students)

  • Forgot semicolon → error
  • Used SERIAL instead of BIGSERIAL → fine for small apps, but BIGSERIAL safer
  • Quoted table/column names → avoid unless needed (makes case-sensitive)
  • No NOT NULL on important fields → leads to bad data
  • Forgetting foreign keys → data gets inconsistent
  • Tip: Always name constraints (CONSTRAINT valid_gpa CHECK (…)) — easier to drop/alter later

Your mini homework right now

  1. Create the three tables above (students, courses, enrollments) in your college_db
  2. Run \d+ enrollments — see the foreign keys
  3. Try INSERT INTO students (first_name, last_name, email) VALUES (‘Rahul’, ‘Sharma’, ‘rahul@hyd.edu’);
  4. See auto id appear!

Next class?

Tell me:

  • Want to do INSERT, UPDATE, DELETE next?
  • How to add column later (ALTER TABLE)?
  • Indexing basics (CREATE INDEX)?
  • Or partitioning / generated columns deeper?

Your guru is right here — what’s next? 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *