Lesson 15 of 2225 min read

PRIMARY KEY and AUTO_INCREMENT in SQL: Single and Composite Keys Explained

Understand PRIMARY KEY and AUTO_INCREMENT in MySQL, including single-column and composite primary keys, with real examples.

PRIMARY KEY and AUTO_INCREMENT in SQL: Single and Composite Keys Explained

Every row in a well-designed table needs a way to be uniquely identified — a row's fingerprint that no other row can share. That's exactly what PRIMARY KEY guarantees, and AUTO_INCREMENT is the convenient mechanism MySQL provides to generate those identifiers automatically. This lesson covers single-column and composite primary keys, how AUTO_INCREMENT works under the hood, and when each pattern fits best.

What Is a PRIMARY KEY?

A PRIMARY KEY is a constraint that uniquely identifies every row in a table. It combines NOT NULL and UNIQUE automatically — a primary key column can never be empty and can never repeat across rows. A table can have only one PRIMARY KEY, though that key can span a single column or multiple columns together as a composite key.

What You'll Learn

  • Define single-column primary keys using PRIMARY KEY and AUTO_INCREMENT.
  • Design composite primary keys spanning multiple columns.
  • Understand how AUTO_INCREMENT generates sequential values automatically.
  • Compare surrogate keys (auto-generated IDs) versus natural keys (real-world unique values).

Key Terms to Know

  • Primary key: A column or set of columns that uniquely identifies each row in a table.
  • AUTO_INCREMENT: A MySQL column attribute that automatically generates the next sequential integer value on insert.
  • Composite primary key: A primary key made up of two or more columns combined.
  • Surrogate key: An artificially generated identifier, like an auto-incrementing ID, with no real-world meaning.
  • Natural key: A primary key based on a real-world unique attribute, like a national ID number or ISBN.

Single-Column Primary Keys with AUTO_INCREMENT

The most common pattern in MySQL is a single integer column marked PRIMARY KEY AUTO_INCREMENT, such as customer_id INT PRIMARY KEY AUTO_INCREMENT. Every time a new row is inserted without specifying that column, MySQL automatically assigns the next available integer, starting from 1 by default and increasing with each insert.

This is called a surrogate key — it has no real-world meaning, it exists purely to uniquely identify rows efficiently. Surrogate keys are popular because they're small, fast to index, and never need to change even if real-world data like a name or email changes.

Composite Primary Keys: When One Column Isn't Enough

Sometimes uniqueness only makes sense when two or more columns are combined. In an enrollments table linking students to courses, neither student_id nor course_id alone is unique — many students take many courses — but the combination of (student_id, course_id) is unique, since a student shouldn't enroll in the same course twice.

A composite primary key is defined at the table level: PRIMARY KEY (student_id, course_id). MySQL then enforces that no two rows can share the same combination of values across both columns, while either column individually can repeat.

AUTO_INCREMENT Behavior and Gotchas

AUTO_INCREMENT values are not reused after a row is deleted by default — if row 5 is deleted, the next inserted row still gets 6, not 5. This is intentional, since reusing IDs could cause confusion if external systems, logs, or URLs reference the old ID 5.

You can control the starting value with AUTO_INCREMENT = 1000 in the table options, which is useful when migrating data or avoiding ID collisions across systems. AUTO_INCREMENT can only be applied to one column per table, and that column must also be indexed (it usually is, since it's typically the primary key).

Visual Summary

Picture a primary key as a unique locker number assigned to every row — no two rows ever share a locker, and every row must have one. AUTO_INCREMENT is the automated locker attendant who hands out the next unused number every time a new row walks in, without anyone having to manually pick one.

Single vs Composite Primary Keys

AspectSingle-Column KeyComposite Key
Columns involvedOne column (often an ID)Two or more columns combined
Typical useMost standalone entity tablesJoin/association tables (e.g. enrollments)
AUTO_INCREMENT compatibleYes, very common pairingNot typically used on composite keys
Uniqueness ruleThat one column never repeatsThe combination never repeats; individual columns can

SQL Example

-- Single-column primary key with AUTO_INCREMENT
CREATE TABLE students (
  student_id   INT PRIMARY KEY AUTO_INCREMENT,
  student_name VARCHAR(100) NOT NULL
);

CREATE TABLE courses (
  course_id   INT PRIMARY KEY AUTO_INCREMENT,
  course_name VARCHAR(100) NOT NULL
);

-- Composite primary key linking students and courses
CREATE TABLE enrollments (
  student_id   INT,
  course_id    INT,
  enrolled_on  DATE NOT NULL DEFAULT (CURRENT_DATE),
  PRIMARY KEY (student_id, course_id),
  FOREIGN KEY (student_id) REFERENCES students(student_id),
  FOREIGN KEY (course_id) REFERENCES courses(course_id)
);

students and courses each use a simple AUTO_INCREMENT surrogate key, since each row independently needs a unique identifier. enrollments uses a composite primary key on (student_id, course_id) because the same student can appear in many rows and the same course can appear in many rows — only the combination of both together must be unique, preventing duplicate enrollment in the same course.

Real-World Examples

  • E-commerce platforms use AUTO_INCREMENT order_id columns so every order gets a guaranteed unique, sequential identifier.
  • Social media platforms use composite primary keys on tables like (user_id, post_id) for likes, ensuring a user can't like the same post twice.
  • Banking systems often use surrogate keys for accounts internally while also storing a natural key like an account number for customer-facing reference.
  • Ride-hailing apps use composite keys on (driver_id, trip_id) style association tables to track which driver handled which trip without duplication.

Best Practices and Pro Tips

  • Default to a surrogate AUTO_INCREMENT primary key for most entity tables — it's simpler, faster to index, and immune to real-world data changes like a customer changing their email.
  • Reserve composite primary keys for genuine many-to-many association/junction tables, where the natural uniqueness really does depend on a combination of foreign keys.
  • If you ever need to migrate or merge data from multiple systems, plan AUTO_INCREMENT starting ranges in advance to avoid ID collisions between systems.

Common Mistakes to Avoid

  • Assuming deleted AUTO_INCREMENT values get reused — they don't by default, which can cause confusing gaps in ID sequences that are completely normal.
  • Using a 'natural' key like email as a primary key, then running into problems when that value legitimately needs to change.
  • Forgetting that a composite primary key requires both columns together, not either column individually, to enforce uniqueness.
  • Adding AUTO_INCREMENT to a column that isn't indexed or isn't the primary/unique key, which MySQL will reject.

Interview Questions

Q1. What two constraints does PRIMARY KEY automatically combine?

PRIMARY KEY automatically enforces both NOT NULL and UNIQUE — the column (or columns) can never be empty and can never contain duplicate values across rows.

Q2. What is a composite primary key, and when would you use one?

A composite primary key is a primary key made of two or more columns combined, used when no single column alone guarantees uniqueness. It's common in many-to-many association tables, like (student_id, course_id) in an enrollments table.

Q3. Does MySQL reuse AUTO_INCREMENT values after a row is deleted?

No, by default MySQL does not reuse AUTO_INCREMENT values after deletion. If the highest ID row is deleted, the next inserted row still continues from where the counter left off, creating an intentional gap.

Q4. What is the difference between a surrogate key and a natural key?

A surrogate key is an artificially generated identifier, like an AUTO_INCREMENT integer, with no real-world meaning. A natural key is based on a real-world unique value, like an email address, passport number, or ISBN.

Practice MCQs

1. Which two constraints does PRIMARY KEY combine automatically?

  1. UNIQUE and CHECK
  2. NOT NULL and UNIQUE
  3. DEFAULT and CHECK
  4. FOREIGN KEY and UNIQUE

Answer: B. NOT NULL and UNIQUE

Explanation: A primary key column can never be NULL and can never have a duplicate value, combining both constraints automatically.

2. In an enrollments table linking students and courses, why is a composite key on (student_id, course_id) appropriate?

  1. Because student_id alone must be unique
  2. Because course_id alone must be unique
  3. Because the combination of both must be unique, not either column alone
  4. Because composite keys are required by MySQL

Answer: C. Because the combination of both must be unique, not either column alone

Explanation: Either column alone can repeat across rows; only the specific pairing of student and course must be unique to prevent duplicate enrollment.

3. What happens to an AUTO_INCREMENT counter after the highest-ID row is deleted?

  1. It resets to 1
  2. It reuses the deleted value next
  3. It continues from where it left off, leaving a gap
  4. AUTO_INCREMENT stops working

Answer: C. It continues from where it left off, leaving a gap

Explanation: By default, MySQL does not reuse AUTO_INCREMENT values after deletion, so a gap in the sequence is normal and expected.

Quick Revision Points

  • PRIMARY KEY = NOT NULL + UNIQUE, and only one per table.
  • A composite primary key spans multiple columns; only their combination must be unique.
  • AUTO_INCREMENT auto-generates the next integer; deleted values are not reused by default.
  • Surrogate keys (auto-generated) are generally preferred over natural keys for primary keys.

Conclusion

  • PRIMARY KEY is the foundation of row-level uniqueness in every relational table.
  • AUTO_INCREMENT removes the burden of manually generating unique IDs.
  • Composite keys solve uniqueness problems that no single column can solve alone.

PRIMARY KEY guarantees that every row in a table can be uniquely and reliably identified, combining NOT NULL and UNIQUE into one enforced rule. AUTO_INCREMENT automates the generation of simple sequential surrogate keys, while composite primary keys solve uniqueness for association tables where no single column suffices. With unique identification covered, the next lesson — FOREIGN KEY — explains how tables reference each other's primary keys to build real relational structure.

Frequently Asked Questions

No, a table can only have one PRIMARY KEY definition, though that single primary key can be composite, spanning multiple columns. If you need additional unique columns, use the UNIQUE constraint instead.

AUTO_INCREMENT works with any integer type (INT, BIGINT, SMALLINT, etc.) and also with floating-point types in MySQL, though using it with non-integer types is uncommon. INT and BIGINT are the standard choices in practice.

Specify it as a table option: CREATE TABLE orders (...) AUTO_INCREMENT = 1000;, which makes the first inserted row start at 1000 instead of 1. You can also change it later with ALTER TABLE orders AUTO_INCREMENT = 5000;.

In most modern applications, yes — surrogate keys are simpler to index, never change, and avoid issues if a 'natural' unique value turns out not to be as permanent as assumed. Natural keys can still be kept as UNIQUE columns for business-level uniqueness.

Yes, this is extremely common in association/junction tables, where both columns in the composite primary key are also individually defined as foreign keys referencing other tables, as seen in the enrollments example.