Dataslope logoDataslope

Foreign Keys

Learn how foreign keys encode relationships between tables by pointing stable references at primary keys.

An order belongs to a customer. A comment belongs to a post. A payment belongs to an invoice. In a database design, those sentences must become columns and constraints.

A foreign key is the design tool that turns "belongs to" into a trustworthy relationship.

A relationship needs a reference

A foreign key is a column in one table that stores the primary key value of a related row in another table.

The orders.customer_id column points at customers.customer_id. One customer can have many orders, and each order belongs to one customer.

That arrow is more than a drawing. When you declare the constraint, PostgreSQL checks that the referenced customer actually exists.

Why store an id instead of duplicating data?

A tempting design is to copy the customer's name and email onto every order. That feels simple until the data changes.

A foreign key keeps the customer's facts in one place and stores only the stable identity on related rows.

This is a design for consistency. The order does not need its own copy of the customer's email; it needs a reliable reference to the customer.

Quick check

QuestionSelect one

In a well-designed orders table, why store customer_id instead of customer_email and customer_name on every order?

Because names and emails cannot be queried with SQL.

Because the customer row stays the single source of truth while orders keep a stable reference.

Because every order must have a different customer.

Because PostgreSQL refuses to store text in an orders table.

Foreign keys enforce the relationship

A foreign key is not just documentation. It is a rule the database defends. If an order points to customer 999 and no such customer row exists, PostgreSQL rejects the order.

SQL
PostgreSQL 17

The rejected insert prevents an orphan row: a child row whose parent row does not exist.

Parent and child tables

When discussing foreign keys, people often say parent table and child table.

  • The parent table is the table being referenced.
  • The child table is the table holding the foreign key.

The child points to the parent because the child row depends on the parent's identity. An order cannot meaningfully belong to a customer who does not exist.

Quick check

QuestionSelect one

What does a foreign key constraint add beyond simply naming a column customer_id?

It makes the column display with a special color in SQL results.

It causes all customers to have exactly one order.

It makes PostgreSQL verify that each stored id points to an existing parent row.

It copies the customer's name into the order automatically.

Foreign keys describe cardinality

Foreign keys often encode cardinality, the shape of a relationship. In the common one-to-many case, many child rows can reference one parent row.

The foreign key lives on the many side: each book stores the author it belongs to. If a book could have many authors too, the design would need a separate junction table, not just one author_id column.

Check your understanding

QuestionSelect one

What is a foreign key?

A column that stores a random value unrelated to other tables.

A column or columns that reference a primary key or unique key in another table.

A required copy of every column from the parent table.

A second table name written inside a query.

QuestionSelect one

In a customer-order design, which table is usually the child table?

customers, because customers have names.

orders, because each order stores customer_id and depends on a customer.

Both tables, because every table must have the same columns.

Neither table, because parent and child only apply to file systems.

QuestionSelect one

What happens when a foreign key blocks customer_id = 99 in orders?

PostgreSQL creates customer 99 automatically.

PostgreSQL changes 99 to null silently.

The insert is rejected because no referenced customer row exists.

The whole database is deleted.

QuestionSelect one

Where does the foreign key usually live in a one-to-many relationship?

On the one side, because it has fewer rows.

On the many side, because each child row points to the one parent row it belongs to.

In a separate database that stores only keys.

In every column of both tables.

On this page