CREATE and INSERT commands are DDL (Data Definition Language) and DML (Data Manipulation Language) respectively. They form the foundation of working with PostgreSQL — you define structure first, then populate it with data.
CREATE DATABASE
CREATE TABLE
Basic syntax
Example — employees table
Example — with foreign key
Common data types
| Type | Description | Example |
|---|---|---|
SERIAL | Auto-incrementing integer | id SERIAL PRIMARY KEY |
INT / INTEGER | Whole numbers | age INT |
NUMERIC(p, s) | Exact decimal with precision p and scale s | salary NUMERIC(10, 2) |
VARCHAR(n) | Variable-length string up to n chars | name VARCHAR(100) |
TEXT | Unlimited-length string | bio TEXT |
BOOLEAN | TRUE / FALSE | is_active BOOLEAN |
DATE | Calendar date (no time) | hire_date DATE |
TIMESTAMP | Date + time | created_at TIMESTAMP |
UUID | Universally unique identifier | id UUID DEFAULT gen_random_uuid() |
JSONB | Binary JSON (indexable) | metadata JSONB |
Column constraints
| Constraint | Meaning |
|---|---|
PRIMARY KEY | Unique + NOT NULL, identifies each row |
NOT NULL | Column cannot be empty |
UNIQUE | No duplicate values allowed |
DEFAULT value | Fallback value when none is provided |
CHECK (expr) | Custom validation rule |
REFERENCES table(col) | Foreign key — must match a value in another table |
Table-level constraints
◆ PRIMARY KEY vs UNIQUE
A table can have only one
PRIMARY KEY (which is UNIQUE + NOT NULL), but multiple UNIQUE constraints. UNIQUE columns can contain NULL values (and multiple NULLs are considered distinct).ALTER TABLE
Modify an existing table without recreating it.DROP TABLE & TRUNCATE
◆ DROP vs TRUNCATE vs DELETE
DROP removes the table entirely (structure + data). TRUNCATE removes all rows instantly but keeps the table structure — it’s faster than
DELETE because it doesn’t scan rows. DELETE removes rows one by one and can be filtered with WHERE.INSERT INTO
Single row
Multiple rows
Insert with DEFAULT values
Insert with RETURNING
PostgreSQL-specific — returns the inserted data without a separateSELECT.
Insert from a SELECT (copy data between tables)
ON CONFLICT (Upsert)
Handle duplicate key violations gracefully — insert or update.◆ EXCLUDED keyword
In an
ON CONFLICT ... DO UPDATE clause, EXCLUDED refers to the row that was proposed for insertion. Use EXCLUDED.column_name to reference the values that would have been inserted.💡 Interview Tip
ON CONFLICT (upsert) is a PostgreSQL-specific feature. In MySQL the equivalent is INSERT ... ON DUPLICATE KEY UPDATE. Knowing this distinction shows cross-database awareness.Common interview questions
What is the difference between SERIAL and IDENTITY?
What is the difference between SERIAL and IDENTITY?
Both auto-generate integer values.
SERIAL creates a sequence behind the scenes and is PostgreSQL-specific. GENERATED ALWAYS AS IDENTITY is the SQL-standard way (PostgreSQL 10+) and is preferred in modern code:What happens if you INSERT without specifying all columns?
What happens if you INSERT without specifying all columns?
Columns not listed in the
INSERT statement receive their DEFAULT value. If a column has no default and is NOT NULL, the insert will fail with an error.What is the difference between VARCHAR and TEXT?
What is the difference between VARCHAR and TEXT?
VARCHAR(n) enforces a maximum length of n characters. TEXT has no length limit. In PostgreSQL, performance is identical — TEXT is generally preferred unless you need a length constraint for data validation.Can you INSERT into a view?
Can you INSERT into a view?
Yes, if the view is simple (single table, no aggregates, no DISTINCT, no GROUP BY). For complex views, you need
INSTEAD OF triggers. Insertable views must map directly to the underlying table columns.