← Back to Glossary

Composite key

A composite key is a primary key made up of two or more columns whose combined values uniquely identify a row, used when no single column is unique on its own.

Overview

A composite key (also called a compound key) combines multiple columns into a single primary key, because no individual column is unique by itself but the combination is. A classic example is a bridge table linking students to courses: neither student_id nor course_id alone identifies a row, but the pair (student_id, course_id) does.

Composite keys show up often in junction/bridge tables that resolve many-to-many relationships, in fact tables at a fine grain (e.g., order_id + line_number), and in time-series data where uniqueness requires both an entity identifier and a timestamp.

Example

Copy code

CREATE TABLE enrollments ( student_id INTEGER, course_id INTEGER, enrolled_on DATE, PRIMARY KEY (student_id, course_id) ); CREATE TABLE fact_order_lines ( order_id INTEGER, line_number INTEGER, product_key INTEGER, quantity INTEGER, revenue DECIMAL(10,2), PRIMARY KEY (order_id, line_number) ); SELECT order_id, SUM(revenue) AS order_total FROM fact_order_lines GROUP BY ALL;

Composite keys are also used as composite foreign keys, referencing another table's composite primary key column-for-column, when a relationship's uniqueness genuinely spans multiple columns.

Trade-offs

Composite keys can make joins more verbose — every join needs to match on all key columns — and can be less efficient to index than a single narrow surrogate key. Many warehouses introduce a single surrogate key even for entities that would naturally have a composite key, purely to simplify downstream joins, keeping the original columns as a UNIQUE constraint instead.

DuckDB angle

DuckDB supports multi-column primary and foreign keys directly with the PRIMARY KEY (col1, col2) syntax shown above, and enforces uniqueness across the combination. For analytical queries, joining on a composite key works the same as joining on a single key — you just list each column pair in the JOIN ... USING or ON clause.

Related terms

FAQS

Composite keys work well for bridge/junction tables and fine-grained fact tables where the natural uniqueness genuinely spans two or more columns. Many teams still add a single surrogate key on top for simpler downstream joins, keeping the composite columns as a unique constraint.