Back to Blog
Lesson 11 of the PostgreSQL: SQL & PostgreSQL from Scratch course
DatabasesJuly 29, 20264 min read

Understanding Primary Keys: Ensuring Data Integrity in PostgreSQL

Learn how to define a Primary Key constraint to ensure data integrity in your PostgreSQL database. Master surrogate keys and serial IDs for your store schema.

PostgreSQLDatabase DesignSQLPrimary KeyData IntegrityConstraints
A vibrant image of a red locker door with a key in the lock, featuring bold primary colors.

Previously in this course, we discussed designing the products table and building the customers table. While we defined the columns for our store application, those tables lacked a fundamental mechanism to guarantee that each record remains distinct and identifiable. In this lesson, we introduce the Primary Key constraint to provide that guarantee.

What is a Primary Key?

A Primary Key is a column (or set of columns) that uniquely identifies every row in a table. Think of it as a fingerprint for your data. In a relational database, you must be able to point to a specific row without ambiguity. If you have two customers named "John Smith," a Primary Key ensures that the database knows exactly which "John Smith" you are updating or deleting.

A column designated as a Primary Key must satisfy two strict rules:

  1. Uniqueness: No two rows can have the same value in the Primary Key column.
  2. Non-nullability: A Primary Key cannot be NULL. Every row must have a valid identifier.

The Power of Surrogate Keys

When designing databases, you might be tempted to use "natural" data as your identifier—like an email address or a SKU. However, natural keys are often unstable. If a customer changes their email address, or a product manufacturer changes their naming convention, your entire database relationship structure could break.

This is why we use Surrogate Keys. A surrogate key is an artificial identifier—usually an integer—that has no business meaning. It exists solely to identify the row. By using a surrogate key, you decouple your database’s internal identifiers from the real-world data, which makes your schema significantly more resilient to change. As discussed in Primary Keys and Identifiers: Designing for Data Integrity, surrogate keys are the gold standard for maintaining Data integrity in professional applications.

Implementing Serial IDs

PostgreSQL provides a convenient way to implement surrogate keys using the SERIAL pseudo-type. When you define a column as SERIAL, PostgreSQL automatically creates a sequence object that generates a unique, auto-incrementing integer every time you insert a new row.

Let’s apply this to our products table.

SQL
CREATE TABLE products (
    product_id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    price NUMERIC(10, 2) NOT NULL,
    stock_quantity INTEGER DEFAULT 0
);

In the statement above:

  • product_id SERIAL: Automatically creates an integer column and hooks it to a sequence.
  • PRIMARY KEY: Tells PostgreSQL to enforce uniqueness and disallow NULL values on this column.

Hands-on Exercise: Update your Schema

We need to make our customers table production-ready. Using the logic above, write a CREATE TABLE statement for the customers table that includes a surrogate Primary Key.

Task:

  1. Drop your existing customers table if it exists.
  2. Create a new customers table with:
    • customer_id as a SERIAL PRIMARY KEY.
    • first_name and last_name as TEXT.
    • email as TEXT.
SQL
-- Example solution
DROP TABLE IF EXISTS customers;

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    email TEXT
);

Common Pitfalls

  • Forgetting the PRIMARY KEY: It is common for beginners to define a table without a primary key. This makes it extremely difficult to perform targeted UPDATE or DELETE operations later. Always define one from the start.
  • Over-using Composite Keys: While you can use multiple columns as a primary key, it adds complexity to your queries and relationships. Stick to a single SERIAL or UUID column whenever possible.
  • Assuming Sequence Continuity: If you delete a row, the SERIAL ID will not "fill the gap." If you insert IDs 1, 2, and 3, and delete 2, the next ID will be 4. Never rely on these IDs being perfectly sequential without gaps.

FAQ

Can a table have more than one Primary Key? A table can have only one Primary Key constraint. However, that constraint can be composed of multiple columns (a "composite key").

Should I use SERIAL or UUID? SERIAL is perfect for beginners and small-to-medium applications. UUID (discussed later in this course) is better for distributed systems where you need to generate IDs on the client side before saving to the database.

What happens if I try to insert a duplicate ID? PostgreSQL will throw a unique_violation error, preventing the transaction from completing, which is exactly the protection you need for your data.

Recap

Primary Keys are the foundation of relational Data integrity. By using SERIAL surrogate keys, you ensure that every record in your store database is uniquely addressable, regardless of changes to the underlying business data.

Up next: We will learn how to connect these tables together using Foreign Keys to establish relationships between your customers and their orders.

Similar Posts