Question: What is a DEFAULT constraint in SQL?
Answer: A DEFAULT constraint tells the database what value to put into a column when an INSERT does not provide one. It is commonly used for things like status flags, timestamps, and simple fallback values. The key gotcha is that a default is used only when the column is omitted; if you explicitly insert NULL, the default does not automatically replace it.
Interview-Ready Answer: I use a DEFAULT constraint to give a column a fallback value when the insert statement leaves that column out. It keeps data consistent and reduces application code, especially for fields like status, priority, and created_at. The most important detail is that omitted is not the same as NULL: if I send an explicit NULL, the default does not fire. So I think of DEFAULT as the database’s backup plan, while NOT NULL and CHECK handle validation.
A DEFAULT is part of the column definition. It is a built-in fallback value that the database can supply for you, so the application does not have to repeat the same literal over and over. This is why interviewers like it: it sounds simple, but it reveals whether you understand the difference between missing and null.
INSERT arrives, the engine builds a new row from the supplied values.NULL.NOT NULL, CHECK, UNIQUE, and foreign keys.This means DEFAULT is not really a validator. It does not say, “this data is bad.” It says, “if you did not tell me what to use, I will choose a safe starting value.”
'NEW', 'PENDING', or 'ACTIVE'.CURRENT_TIMESTAMP for creation time.3 or quantity of 1.FALSE as the safe default.| Feature | Main job | What it does |
|---|---|---|
| DEFAULT | Fill missing values | Supplies a value when omitted |
| NOT NULL | Reject empties | Forbids explicit NULL |
| CHECK | Validate rule | Rejects values outside a condition |
A useful mental model is: DEFAULT fills the blank, NOT NULL blocks emptiness, CHECK blocks bad values. They solve different problems and often work best together.
Default lookup is basically O(1) per inserted row, so the overhead is tiny. If the default is a simple literal like 'NEW', the engine just copies it. If the default is a function such as CURRENT_TIMESTAMP, the database evaluates it at insert time; the exact timing can vary by engine, but the key point is that the value comes from the database, not the client.
NULL: default is bypassed.Memory trick: think of DEFAULT as a pre-filled sticky note on a form: if you leave the box untouched, the note stays; if you write your own answer, your choice wins. If you write NULL, that is still an explicit choice, not a blank.
Imagine an e-commerce checkout service with an orders table. The team sets status to default to 'PENDING' so every new order starts in the same safe state, and created_at defaults to the current time so support can trace the order lifecycle.
One day, a bulk migration script loads legacy orders and accidentally inserts NULL into status instead of omitting the column. Because DEFAULT only applies when the column is missing, those rows keep NULL. A background worker that processes WHERE status = 'PENDING' skips them, so the orders never move forward.
What goes wrong: customers see payment confirmations, but fulfillment never starts. Logs show rows with NULL status or downstream errors like “cannot process order with unknown status.” In dashboards, the number of pending orders looks strangely low, while support tickets and retries start climbing. This is exactly the kind of outage a tiny misunderstanding about DEFAULT can cause.
CREATE TABLE task_queue (
task_id INTEGER NOT NULL,
title VARCHAR(50) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'NEW',
priority INTEGER NOT NULL DEFAULT 3,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Because status, priority, and created_at are omitted, the database fills them in.
INSERT INTO task_queue (task_id, title) VALUES (1, 'Send email');
-- Explicit values always win over the default.
INSERT INTO task_queue (task_id, title, status, priority) VALUES (2, 'Charge card', 'PENDING', 1);
-- This would fail in most databases because NULL is explicit, so DEFAULT is not used.
-- Since status is also NOT NULL, the row is rejected instead of silently falling back.
-- INSERT INTO task_queue (task_id, title, status) VALUES (3, 'Bad row', NULL);
-- Show the rows that were inserted successfully.
SELECT task_id, title, status, priority, created_at
FROM task_queue
ORDER BY task_id;Follow-up & Tricky Questions:
CURRENT_TIMESTAMP or other built-in functions, though the exact rules depend on the engine.UPDATE? Not automatically. Defaults are mainly for INSERT; some databases let you write SET col = DEFAULT in an UPDATE, but that is different from a default firing by itself.ALTER TABLE to change the column definition, but remember that old rows usually stay unchanged unless you backfill them with UPDATE.NULL, does the default apply? No. NULL is an explicit value, so the default is skipped; this is the most common interview trap.NOT NULL and CHECK if you need the database to reject bad data.Common Mistakes:
NULL does not.CHECK or application logic for more complex rules.Memory Hook: Omitted gets the default; explicit wins, even if it is NULL. Think of a pre-filled form: if you leave the field alone, the pre-fill stays; if you type anything, your choice overrides it.
Cheat Sheet:
INSERT.NULL does not use the default.NOT NULL for safer data.Practice Tasks:
status column that defaults to 'NEW', then insert one row with the column omitted and one with an explicit value.created_at column with CURRENT_TIMESTAMP as the default, then compare rows inserted at different times.