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
| Aspect | Single-Column Key | Composite Key |
|---|---|---|
| Columns involved | One column (often an ID) | Two or more columns combined |
| Typical use | Most standalone entity tables | Join/association tables (e.g. enrollments) |
| AUTO_INCREMENT compatible | Yes, very common pairing | Not typically used on composite keys |
| Uniqueness rule | That one column never repeats | The 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?
- UNIQUE and CHECK
- NOT NULL and UNIQUE
- DEFAULT and CHECK
- 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?
- Because student_id alone must be unique
- Because course_id alone must be unique
- Because the combination of both must be unique, not either column alone
- 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?
- It resets to 1
- It reuses the deleted value next
- It continues from where it left off, leaving a gap
- 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.