Can Primary Key Be A Foreign Key? | One Column, Two Jobs

Yes, one column can identify a row and point to a parent row, and foreign-key columns can also sit inside a composite ID.

A primary key can be a foreign key. The same column can do two jobs at once: mark one row as that table’s own ID and tie that row to a parent row in another table. You’ll see this most often in one-to-one table splits, subtype tables, and bridge tables where one or more foreign-key columns make up the full row ID.

The rule is simple. The primary-key side says the value must be present and must not repeat inside the table. The foreign-key side says the value must already exist in the parent table. If both statements are true, the design is valid.

The catch is fit. A shared key is tidy when the child row cannot stand on its own. It gets messy when the child row has its own timing or many links in and out.

Can Primary Key Be A Foreign Key? Cases That Fit

There are two common ways the answer becomes “yes.” They solve different problems.

  • Shared primary key: the child table uses the same single column as both its row ID and its link to the parent table. This is a classic one-to-one setup.
  • Composite primary key with foreign keys inside it: one or more columns in the table’s full row ID point to parent tables. This is common in join tables such as student_course or order_item.

In the first pattern, each child row belongs to one parent row and cannot exist without it. In the second, the whole row ID is built from parent IDs, often to block duplicate pairings. Both are normal relational design.

What Each Constraint Is Doing

Primary key job

A primary key gives each row one stable identity inside its own table. That identity cannot be null, and it cannot repeat.

Foreign key job

A foreign key ties one table to another. It stops orphan rows by making sure the referenced parent value already exists.

Where the overlap happens

Nothing in relational design says one column may wear only one badge. If a child table’s ID should always match the parent table’s ID, one column can satisfy both rules at once. The same logic applies to composite IDs. A row in enrollment may use student_id and course_id as its full ID, with both columns pointing outward.

Vendor docs line up on this. Microsoft Learn’s primary and foreign key constraints page lays out the two rules, and PostgreSQL’s constraints section notes that a foreign key may point to a primary key or another duplicate-free column set.

When A Primary Key Also Acts As A Foreign Key

This pattern shines in a child table that adds detail to a parent row. Say you keep core account data in users, then place optional profile data in user_profiles. The child row should never exist before the user exists, and there should never be two profile rows for one user.

CREATE TABLE users (
  user_id INT PRIMARY KEY
);

CREATE TABLE user_profiles (
  user_id INT PRIMARY KEY
      REFERENCES users(user_id),
  bio TEXT,
  avatar_url TEXT
);

Here, user_profiles.user_id does both jobs. It identifies the row in user_profiles, and it points back to users.user_id. If you use an ORM, Microsoft’s EF Core one-to-one relationship docs show this PK-to-PK shape directly.

This setup blocks duplicate child rows, keeps the link simple, and tells every reader of the schema that the child row is fully dependent on the parent row.

Pattern How The Key Works When It Fits
User And Profile Child ID equals parent ID and points to the parent Extra user details live apart from the main row
Employee And Badge Badge row reuses employee ID The badge row should never outlive the employee row
Product And Detail Sheet Detail row uses product ID as both PK and FK Large or optional fields are split from the base table
Order Item order_id is an FK and part of a composite PK Each row belongs to one order and needs its own line ID
Student Course student_id and course_id are both FKs and together form the PK You need one row per student-course pair
Post And SEO Row SEO row reuses post ID Side data is optional but capped at one row
Subtype Table Child type row shares parent ID One base entity branches into narrow child tables

Common Schema Patterns

Table split for optional columns

Some tables grow fat over time. A shared key lets you peel off bulky or sparse columns into a second table without losing a strict one-to-one link.

Subtype tables

A base table may hold all rows in a broad category, then child tables hold type-specific fields. A person row may have one matching employee row or one matching contractor row.

Bridge tables

Join tables are the other big place where this idea shows up. The table’s primary key may be made from two foreign keys together. That does not mean one single column is both PK and FK by itself. It means the row’s full identity includes columns that point to parent tables. That is still a clear “yes” to the wider question.

Use a simple gut check. If the child row can never have two rows for one parent and should not exist alone, shared PK is a strong bet. If the row needs its own identity apart from the parent, add a separate primary key and keep the foreign key separate.

Common Mistake Why It Hurts Better Move
Using shared PK for a one-to-many link You cap the child table at one row per parent Use a separate child PK plus a plain FK
Forcing a child row before it is needed Insert order gets awkward and null workarounds creep in Use a nullable FK or split the timing
Skipping an index on busy FK columns Joins and deletes can slow down badly Add an index where query load calls for it
Using shared PK when the child may move Changing the parent link means changing the row ID Give the child its own PK
Hiding the rule from the team Later edits break the data model Name constraints clearly and note the intent in schema docs

Rules That Keep The Design Clean

If you choose a primary-key-and-foreign-key combo, keep the schema tight. Clean DDL saves headaches later.

  • Pick a clear parent table. The child should depend on it, not the other way around.
  • Use shared PK for one-to-one, not one-to-many.
  • Set delete and update actions on purpose. Blind cascades can bite.
  • Name constraints so the link is easy to read in logs and migrations.
  • Index foreign-key columns in hot join paths when your engine does not do that for you.
  • Keep insert order in mind. Parent row first, child row next is the usual path.

If you are building a bridge table, make the composite primary key match the duplicate rule you want. If one student should appear only once per course, (student_id, course_id) is a clean row ID. If the row needs repeat attempts, terms, or versions, fold that extra column into the key or move to a surrogate ID.

When This Setup Is A Bad Bet

Do not reach for a shared key just because it feels neat. Skip it when the child table may need multiple rows per parent, when the child can switch parents, or when the child row arrives long before the parent row is known. In those cases, a separate child ID keeps life simpler.

Also watch for over-splitting. If two tables are joined on every read and never managed apart, the split may add more friction than value.

The Practical Rule

Yes, a primary key can be a foreign key. Use that pattern when the child row is bound tightly to one parent row and should share the same identity. Use composite keys with foreign-key columns in bridge tables when the row itself is defined by a pair or set of parent IDs. If the child needs room to grow on its own, give it its own primary key and keep the foreign key as just a link.

References & Sources