NOT NULL and UNIQUE are two simple but powerful constraints that keep your data clean and reliable.
NOT NULL
NOT NULL means the column must have a value. You cannot insert a row without providing something for that column.
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
email TEXT NOT NULL
);
-- This works:
INSERT INTO users VALUES (1, 'musa123', 'musa@email.com');
-- This fails because username is NULL:
INSERT INTO users VALUES (2, NULL, 'test@email.com');
Use NOT NULL for columns that are essential — names, emails, prices, anything that does not make sense to be empty.
UNIQUE
UNIQUE ensures that all values in a column are different from each other:
CREATE TABLE users2 (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
email TEXT NOT NULL UNIQUE
);
INSERT INTO users2 VALUES (1, 'musa123', 'musa@email.com');
-- This fails because 'musa123' is already taken:
INSERT INTO users2 VALUES (2, 'musa123', 'other@email.com');
-- This also fails because 'musa@email.com' is already used:
INSERT INTO users2 VALUES (3, 'fatima_dev', 'musa@email.com');
Using Both Together
You can combine NOT NULL and UNIQUE on the same column. That gives you a column that must have a value and must be different from every other value:
CREATE TABLE products (
id INTEGER PRIMARY KEY,
product_code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
price REAL NOT NULL
);
This is very common for things like product codes, national IDs, email addresses, or usernames — values that should always exist and always be unique.