Sling Academy
Home/PostgreSQL/PostgreSQL: Using ‘CREATE DOMAIN’ to create custom data types

PostgreSQL: Using ‘CREATE DOMAIN’ to create custom data types

Last updated: January 04, 2024

Introduction

In PostgreSQL, the CREATE DOMAIN command is a powerful feature that enables you to define custom data types with constraints to maintain data integrity. This tutorial delves into using domains, enhancing database design with clear examples.

Understanding CREATE DOMAIN

Before diving into code, let’s clarify what a domain is in the context of PostgreSQL. A domain is essentially a data type with optional constraints that define valid values that columns of this type can contain. Think of it as creating a custom rulebook for a data type.

Here’s a simple example that creates a domain for a positive integer:

CREATE DOMAIN positive_integer AS INT
CHECK (VALUE > 0);

This domain ensures that any column defined with the type positive_integer cannot contain a negative number or zero.

Basic Usage of Domains

Let’s start by creating a basic domain that restricts a text field to a specific format:

CREATE DOMAIN email_type AS TEXT
CHECK (VALUE ~* '^[^@]+@[^@]+\.[^@]{2,}

Here, email_type is now a domain that ensures any value assigned to it resembles an email address.

Once you have defined a domain, you can use it just like any other data type when creating a table:

CREATE TABLE users (
    name TEXT,
    email email_type
);

The email column is constrained by the email_type domain, enforcing valid email format. Attempting to insert an invalid email will result in an error.

Advanced Domain Usage

Moving onto more complex scenarios, PostgreSQL allows domains to be based on other domains, adding layers of constraints when necessary. For example:

CREATE DOMAIN business_email AS email_type
CHECK (VALUE LIKE '%@mybusiness.com');

This business_email domain builds upon the previously defined email_type to specifically target email addresses belonging to ‘mybusiness.com’.

You can also alter existing domains to tighten or loosen constraints using the ALTER DOMAIN command:

ALTER DOMAIN email_type
ADD CONSTRAINT email_must_have_dot
CHECK (VALUE LIKE '%.%');

This adds an additional check to ensure that email addresses contain at least one dot.

Domain Constraints

Domains can have several constraints such as NOT NULL, CHECK, and others. There’s also the possibility to name constraints for easier identification:

CREATE DOMAIN age_category AS INTEGER
CONSTRAINT must_be_valid_age
CHECK (VALUE > 0 AND VALUE < 130);

This domain will not accept an age less than 1 or greater than 129. Naming the constraint allows you to quickly reference and manage it in the future.

Using Domains with Functions

Domains aren’t just for table columns. They can also be used with function arguments and return types, fostering consistency throughout the database. Here’s a function example that accepts a business_email domain:

CREATE FUNCTION add_business_contact(email business_email, contact_name TEXT)
RETURNS VOID AS $
BEGIN
    -- Function body to add a business contact
END;
$ LANGUAGE plpgsql;

This ensures that the email parameter passed to the function adheres to the business_email constraints.

Managing Domain Dependencies

A significant aspect of domains is handling dependencies. Removing or altering a domain in use can be tricky. PostgreSQL, however, provides tools to navigate this. For instance, to drop a domain without affecting dependent objects, you can use the CASCADE option:

DROP DOMAIN business_email CASCADE;

This command will remove the domain and any constraints associated with it from any tables or functions where it’s in use.

Conclusion

Domains are a robust feature in PostgreSQL that can streamline data validation and consistency across your database. With careful planning and understanding of their constraints, they can become a cornerstone of a reliable and maintainable database schema. Always test and document any changes to domain definitions to avoid potential disruptions in your application.

Next Article: PostgreSQL: Using ‘CREATE TYPE’ to create custom data types

Previous Article: PostgreSQL: ENUM with a default value and a custom schema

Series: PostgreSQL Tutorials: From Basic to Advanced

PostgreSQL

You May Also Like

  • PostgreSQL with TimescaleDB: Querying Time-Series Data with SQL
  • PostgreSQL Full-Text Search with Boolean Operators
  • Filtering Stop Words in PostgreSQL Full-Text Search
  • PostgreSQL command-line cheat sheet
  • How to Perform Efficient Rolling Aggregations with TimescaleDB
  • PostgreSQL with TimescaleDB: Migrating from Traditional Relational Models
  • Best Practices for Maintaining PostgreSQL and TimescaleDB Databases
  • PostgreSQL with TimescaleDB: Building a High-Performance Analytics Engine
  • Integrating PostgreSQL and TimescaleDB with Machine Learning Models
  • PostgreSQL with TimescaleDB: Implementing Temporal Data Analysis
  • Combining PostgreSQL, TimescaleDB, and Airflow for Data Workflows
  • PostgreSQL with TimescaleDB: Visualizing Real-Time Data with Superset
  • Using PostgreSQL with TimescaleDB for Energy Consumption Analysis
  • PostgreSQL with TimescaleDB: How to Query Massive Datasets Efficiently
  • Best Practices for Writing Time-Series Queries in PostgreSQL with TimescaleDB
  • PostgreSQL with TimescaleDB: Implementing Batch Data Processing
  • Using PostgreSQL with TimescaleDB for Network Traffic Analysis
  • PostgreSQL with TimescaleDB: Troubleshooting Common Performance Issues
  • Building an IoT Data Pipeline with PostgreSQL and TimescaleDB