Domain types help you make sure data follows rules before it goes into your database. This keeps your data clean and correct.
Domain types for validation in PostgreSQL
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
PostgreSQL
CREATE DOMAIN domain_name AS base_data_type [ DEFAULT default_expression ] [ CONSTRAINT constraint_name CHECK (expression) ];
A domain is like a custom data type with rules.
You use CREATE DOMAIN once, then use the domain as a column type.
Examples
PostgreSQL
CREATE DOMAIN phone_number AS TEXT CHECK (LENGTH(VALUE) = 10 AND VALUE ~ '^[0-9]+$');
PostgreSQL
CREATE DOMAIN positive_int AS INTEGER CHECK (VALUE > 0);
PostgreSQL
CREATE DOMAIN email_address AS TEXT CHECK (VALUE ~* '^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$');
Sample Program
This example creates a domain for age that must be between 0 and 120. Then it creates a table using that domain. The first insert works, the second fails because age is negative.
PostgreSQL
CREATE DOMAIN age_domain AS INTEGER CHECK (VALUE >= 0 AND VALUE <= 120); CREATE TABLE people ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, age age_domain ); INSERT INTO people (name, age) VALUES ('Alice', 30); INSERT INTO people (name, age) VALUES ('Bob', -5);
Important Notes
Use the keyword VALUE inside CHECK to refer to the data being checked.
Domains help keep your data rules in one place, making your database easier to manage.
When inserting or updating, if data breaks domain rules, PostgreSQL will stop the action with an error.
Summary
Domains are custom data types with built-in validation rules.
They help keep data clean by enforcing rules automatically.
You create a domain once and use it like any other data type in tables.
Practice
1. What is the main purpose of using
domain types in PostgreSQL?easy
Solution
Step 1: Understand what domain types are
Domain types are user-defined data types that include validation rules to ensure data quality.Step 2: Identify the main purpose
The main purpose is to enforce rules automatically when data is inserted or updated, keeping data clean.Final Answer:
To create custom data types with automatic validation rules -> Option BQuick Check:
Domain types = custom types with validation [OK]
Hint: Domains add rules to types, not speed or storage [OK]
Common Mistakes:
- Confusing domains with indexing
- Thinking domains store large files
- Mixing domains with temporary tables
2. Which of the following is the correct syntax to create a domain named
positive_int that only allows positive integers?easy
Solution
Step 1: Recall the correct syntax for domain creation
The syntax is: CREATE DOMAIN name AS base_type CHECK (condition);Step 2: Match the syntax with options
CREATE DOMAIN positive_int AS integer CHECK (VALUE > 0); matches the correct syntax with CHECK and VALUE keyword.Final Answer:
CREATE DOMAIN positive_int AS integer CHECK (VALUE > 0); -> Option AQuick Check:
CREATE DOMAIN ... AS ... CHECK(...) [OK]
Hint: Use CHECK with VALUE keyword in domain creation [OK]
Common Mistakes:
- Using TYPE instead of AS
- Using WHERE or VALIDATE instead of CHECK
- Missing parentheses around condition
3. Given the domain creation:
What will happen if you try to insert
CREATE DOMAIN us_zipcode AS varchar(5) CHECK (VALUE ~ '^[0-9]{5}$');What will happen if you try to insert
'1234a' into a table column of type us_zipcode?medium
Solution
Step 1: Understand the domain's CHECK constraint
The domain requires the value to match exactly 5 digits using a regular expression.Step 2: Check the value '1234a' against the regex
'1234a' contains a letter, so it does not match the pattern of 5 digits.Final Answer:
The insert will fail due to the CHECK constraint violation -> Option DQuick Check:
Regex check fails = insert rejected [OK]
Hint: Regex in CHECK rejects invalid patterns [OK]
Common Mistakes:
- Assuming varchar allows any string without checks
- Thinking invalid data stores as NULL automatically
- Confusing constraint violation with syntax error
4. You have this domain:
Which of the following INSERT statements will cause an error when inserting into a column of type
CREATE DOMAIN non_empty_text AS text CHECK (LENGTH(VALUE) > 0);
Which of the following INSERT statements will cause an error when inserting into a column of type
non_empty_text?medium
Solution
Step 1: Understand the CHECK condition
The domain requires text length to be greater than 0, so empty strings fail. Whitespace-only strings pass as they have length > 0.Step 2: Evaluate each insert value
INSERT INTO table_name (col) VALUES (''); inserts an empty string '', length 0, violating the check.Final Answer:
INSERT with empty string '' causes error -> Option AQuick Check:
Empty string fails length > 0 check [OK]
Hint: Empty strings fail length > 0 check [OK]
Common Mistakes:
- Thinking whitespace strings fail (they pass)
- Assuming empty string is allowed
- Confusing syntax errors with constraint errors
5. You want to create a domain
rating that stores integers from 1 to 5 inclusive. Which domain definition correctly enforces this range and can be used in multiple tables?hard
Solution
Step 1: Understand the required range
The rating must include 1 and 5, so boundaries are inclusive.Step 2: Analyze each CHECK condition
The option using WHERE instead of CHECK has invalid syntax.
CREATE DOMAIN rating AS integer CHECK (VALUE > 1 AND VALUE < 5); excludes 1 and 5.
CREATE DOMAIN rating AS integer CHECK (VALUE >= 1 AND VALUE <= 5); uses >= 1 AND <= 5, correctly including boundaries.
CREATE DOMAIN rating AS integer CHECK (VALUE IN (1, 2, 3, 4)); uses IN list which misses 5.Step 3: Choose the best option for clarity and standard usage
CREATE DOMAIN rating AS integer CHECK (VALUE >= 1 AND VALUE <= 5); is clear, standard, and commonly used for range checks.Final Answer:
CREATE DOMAIN rating AS integer CHECK (VALUE >= 1 AND VALUE <= 5); -> Option CQuick Check:
Inclusive range uses >= and <= [OK]
Hint: Use >= and <= for inclusive numeric domain checks [OK]
Common Mistakes:
- Using > and < excludes boundary values
- Using WHERE instead of CHECK
- Incomplete IN list misses values
