Natural vs Surrogate Keys in the AI Era: An Old Database Decision With New Consequences

JD
Natural vs Surrogate Keys in the AI Era — database identity architecture
IN BRIEF
Natural keys carry business meaning; surrogate keys provide stable technical identity. A surrogate key does not eliminate the business key — it separates persistence identity from business uniqueness. For long-lived enterprise entities, surrogate keys usually scale better across systems, while natural keys still make sense for genuinely stable reference data. In AI-enabled enterprises, identity resolution across CRM, ERP, data platforms and AI systems becomes more important than the primary-key choice itself. In practice, a hybrid approach is often the most robust.

Some architecture debates never really disappear. They simply become less visible.

Natural keys versus surrogate keys is one of them.

When I started working with databases and enterprise applications, I encountered natural and composite keys much more frequently. An account had an account number. A branch had a branch code. A product had a product code. In many data models, the identifier was closely connected to what the entity actually represented in the business.

Over the years, I have seen the centre of gravity move strongly towards surrogate keys.

Create a table. Add an ID. Make it the primary key. Let the database, ORM or application framework generate it. Move on.

There are good reasons why this approach became popular. I have designed systems using both models throughout my career, and for many large transactional systems I too would generally lean towards a surrogate identifier today.

But I also think the pattern is sometimes applied too automatically. The question I would rather ask first is a little more basic:

What exactly are we trying to identify — a database row, or the business entity represented by that row?

Those two questions are related, but they are not always the same.

And now that the same data routinely travels across ERP systems, CRMs, APIs, analytical platforms and AI applications, that distinction matters more than it did when the database itself was the centre of the application.

Natural Keys — or What I Sometimes Think of as “Organic Keys”

The accepted database term is, of course, natural key.

But I sometimes like to think of natural keys as organic keys. Not as a formal term — simply as a way of thinking about them.

A natural key already exists in the business domain. We discover it; we do not create it purely for the database.

Natural / “Organic” identity
CountryCode = IN
CurrencyCode = INR
AirportCode = DEL
EmployeeCode = EMP-10482
ProductCode = PRD-7281
Surrogate identity
CountryID = 91
CurrencyID = 17
AirportID = 3842
EmployeeID = 583921
ProductID = 7291842

The values on the left tell us something about the entity even before we look at another table. The values on the right usually tell the system a lot and the user almost nothing.

That makes natural keys intuitive. It does not necessarily make them the better architectural choice.

The Problem With “Natural” Is That Business Reality Changes

A natural identifier often looks permanent when the system is first designed.

The problem is the word permanent.

An employee code may contain an organisation or location code. The employee moves. A customer number may follow one company's numbering scheme. Two companies merge. A product code may change after an ERP migration. A supplier identifier may be unique only inside one source system. A booking reference may be unique within a provider, but not necessarily across every provider with which an enterprise integrates.

I have learned to be cautious whenever a design discussion contains the sentence, “this value will never change.” In enterprise systems, never is a very long time.

This is where surrogate keys are powerful. The persistence identity of an entity can remain stable even when its business identifiers change.

CustomerID = 9182741 ← internal identity CustomerCode = IND-45821 ← business identity LegacyCustomerID = C77829 CRMCustomerID = SF-184739

CustomerID can remain untouched while the identifiers around it evolve.

But a Surrogate Key Does Not Remove the Business Key

This is the part that is sometimes missed when teams adopt the “every table gets an ID” convention.

CUSTOMER -------------------------------- CustomerID BIGINT PK CustomerCode VARCHAR(...) CustomerName ...

The table now has a perfectly good primary key. But suppose the business rule says that CustomerCode must be unique.

What stops this?

CustomerID CustomerCode ---------- ------------ 18271 CUST-IN-10482 19410 CUST-IN-10482

The surrogate key is happy. The business is not.

We still need to model the business rule:

CustomerID PRIMARY KEY CustomerCode UNIQUE
🔎
The distinction matters: a surrogate key gives a row a stable technical identity. It does not automatically define the uniqueness of the business entity.

That is why I do not see a surrogate key as a replacement for the natural key. More often, it is a separation of concerns: one identity for persistence, another set of attributes defining business uniqueness.

The “Every Table Needs Its Own ID” Fallacy

One side effect of modern frameworks and code generators is that developers can start treating a separate ID column almost as part of the syntax of creating a table.

Consider a genuine one-to-one extension of an Employee entity:

EMPLOYEE ------------------------- EmployeeID PK EMPLOYEE_PROFILE ------------------------- EmployeeID PK + FK OtherAttributes...

The profile shares the identity of the employee. That is perfectly legitimate.

Yet it is common to see:

EMPLOYEE_PROFILE ------------------------- ProfileID PK EmployeeID FK UNIQUE OtherAttributes...

Now we generate another identity and then add a uniqueness constraint to establish that only one profile can exist for an employee.

There are cases where this is absolutely justified — perhaps the profile will later have its own lifecycle or relationships. But if it will not, the additional ID may simply be ceremony.

Using surrogate keys does not mean that every table needs an independently generated surrogate key.

The lifecycle of the entity should drive the model, not the default template of the ORM.

Natural Keys Can Make Relationships More Expressive

One thing I still like about natural keys is that a relationship can sometimes explain itself.

BRANCH -------------------------------- CompanyCode CountryCode BranchCode PRIMARY KEY (CompanyCode, CountryCode, BranchCode)

A dependent table carrying the same columns makes the business relationship visible in the data model.

Composite natural keys can therefore be elegant from a domain perspective. Relational databases support them perfectly well.

The problem starts when that identity has to travel everywhere.

If CompanyCode + CountryCode + BranchCode is repeated through twenty transaction tables, APIs, DTOs, event messages and ORM relationships, the logical elegance starts creating practical friction.

A single BranchID is much easier to propagate.

This is one of the strongest practical arguments for surrogate keys in large systems.

Storage, Indexes and Joins: There Is No Universal Winner

It is tempting to say that a surrogate key takes more storage because we are adding an extra column. That is sometimes true, but it is only half the picture.

If a natural key consists of three sizeable character columns, every foreign key may have to repeat all three. Replace that with a single BIGINT and the dependent tables — and their indexes — can become substantially narrower.

On the other hand, the parent table may now need both:

CustomerID PK CustomerCode UNIQUE

so the database is maintaining technical identity and business uniqueness separately.

The actual storage and indexing trade-off depends on the width of the natural key, the number of child tables, the indexes being maintained, the workload, and the database engine.

⚖️
My rule of thumb: do not decide this argument from the parent table alone. Look at how widely the key will propagate through the complete schema.

Joins follow a similar pattern.

... JOIN Customer C ON O.CompanyCode = C.CompanyCode AND O.BranchCode = C.BranchCode AND O.CustomerNo = C.CustomerNo

versus:

... JOIN Customer C ON O.CustomerID = C.CustomerID

The second is simpler to write, simpler for an ORM to map, and often cheaper to index and compare when the surrogate is a compact numeric value.

I would still avoid the blanket statement that surrogate-key joins are always faster. Cardinality, data types, statistics, indexing, query plans and workload all matter. But when the natural alternative is long or composite, a narrow surrogate usually gives the database and application a simpler join path.

Application Frameworks Changed the Equation Too

Database design today sits inside a larger software ecosystem: ORMs, REST APIs, caches, generic repositories, code-generation tools, event streams and distributed services.

CustomerId OrderId EmployeeId InvoiceId

A single immutable identifier fits these patterns very naturally. Object identity is easier. Generic CRUD code is easier. Cache keys are easier. API paths are easier.

That convenience is real, and it is one reason surrogate keys became so common.

But it is worth keeping one guardrail in mind:

Convenience for the framework should not be allowed to dictate the business data model.

Frameworks change much faster than enterprise data does.

Surrogate Does Not Mean Auto-Increment Integer Anymore

For years, surrogate key almost automatically meant a sequence such as 1, 2, 3, 4...

That is still a perfectly good choice in many systems.

Distributed architectures have simply added more options. UUIDs and other generated identifiers can be created without relying on one central database sequence, which is useful when identity has to be generated across services or nodes.

That creates another design decision. A UUID has different generation and distribution properties from a sequential BIGINT, but it is also wider and can behave differently in indexes and operational debugging.

So even after deciding to use a surrogate key, the work is not finished. We still have to decide what kind of surrogate key makes sense for this system.

Where I Would Still Happily Use Natural Keys

I do not believe every entity requires a fabricated identity.

For small reference entities with a short, standard and genuinely stable identifier, a natural key can still be the cleanest model.

CURRENCY ---------------- CurrencyCode PK CurrencyName INR USD EUR

Would adding CurrencyID = 47 make this design better? Possibly, if the surrounding architecture has a reason for it. But I would not add it simply because every table is expected to have an ID.

I am most comfortable with a natural primary key when the identifier is:

short and genuinely stable well understood across the domain already guaranteed unique independent of volatile business processes unlikely to be merged, reassigned or reformatted commonly exchanged with other systems in the same form

Where I Strongly Prefer Surrogate Keys

At the other end are long-lived enterprise entities: customers, employees, suppliers, orders, invoices, assets, accounts, and products that may exist across multiple systems.

A customer can easily accumulate several identifiers during its lifetime:

InternalCustomerID CRMCustomerID LegacyCustomerID CustomerCode TaxIdentifier LoyaltyNumber ExternalPartnerID

Which one should define the physical identity of that row for the next fifteen years?

Often, none of them.

That is exactly where an internal surrogate identity earns its place.

And Then Came the AI Layer

This is where an old database-design discussion becomes unexpectedly current.

AI does not change relational theory. A primary key is still a primary key, and a foreign key is still a foreign key.

What AI changes is the amount of context we try to assemble from different systems at the same time.

Identity across the enterprise
One customer. Many system identities.
CRM Customer ID = 18372 ERP Customer ID = 729182 Website User ID = 63729 Legacy Customer Code = AFR-19282 Loyalty ID = SG-882917 CRM → ERP → Data Platform → Customer 360 ↓ Search / Vector Store ↓ AI Assistant / Agent
The key question is no longer only “what is the Customer table's primary key?” It is “how do we know all of these records represent the same customer?”

That is an enterprise identity problem, and it sits underneath a surprising number of AI use cases.

A retrieval system may find three customer records. An AI agent may pull transactions from an ERP and interaction history from a CRM. A customer-service assistant may combine profile, booking, payment and communication data.

If identity resolution is weak, the AI layer may receive incomplete, duplicated or conflicting context.

🧠
This is the AI-era consequence: better prompting cannot repair an underlying identity model that does not reliably tell us which records belong to the same real-world entity.

The AI layer may be new. The data problem underneath it is not.

The Hybrid Approach Has Usually Served Me Best

Having worked with both approaches, I do not see natural versus surrogate keys as an ideological choice.

My preference is usually hybrid.

For a long-lived business entity, I am comfortable using a surrogate key as the stable technical identity. At the same time, I still want the natural or business key to be explicitly identified and protected.

CUSTOMER ----------------------------------------- CustomerID BIGINT PRIMARY KEY CustomerCode VARCHAR(...) UNIQUE ExternalCRMID VARCHAR(...) LegacyCustomerID VARCHAR(...) ...

For a small reference entity with a truly stable and meaningful natural identifier, I may simply use the natural key.

The decision should follow the domain and the lifecycle of the entity — not an ORM default, a database fashion, or a blanket architecture rule.

A Few Questions I Would Ask in a Design Review Today

Does a genuine natural identifier exist? If yes, is it really immutable, or do we only believe today that it will never change? Is the natural key short or composite? A three-column identity propagated through dozens of tables is very different from a three-character reference code. Does the entity exist independently of its current business identifier? Customers, employees and suppliers often do. Will several systems create their own identifiers for the same entity? If yes, a stable internal identity becomes more useful. How widely will this key travel? Tables are only part of the picture now; APIs, events, caches and integrations matter too. Does a child table really have an independent identity? If not, it may not need another generated ID. What happens during mergers, migrations and master-data consolidation? A key that looks perfect inside one application may become awkward when systems coexist. Are we modelling the domain, or merely satisfying a framework convention?

And one question I would add today that I would probably not have asked in the same way twenty years ago:

If an AI application asks for everything we know about this customer, employee, supplier or product five years from now, will we still know which entity it means?

Closing Thought

Natural keys appeal to me because they emerge from the business. Surrogate keys are powerful because they allow system identity to survive changes in that business.

I have used both approaches over the years and still see good reasons for both.

What I would avoid is turning either approach into a rule that no longer requires thought.

The primary-key decision determines how a database identifies a row.

The bigger architecture decision is how the enterprise identifies the thing that row represents.

In increasingly connected, data-driven and AI-enabled enterprises, the second question is becoming harder — and more important — than ever.

A condensed version of this article is available on LinkedIn. For more insights on data architecture, AI system design and enterprise technology leadership, visit kmchronicle.com.

#DatabaseArchitecture #DataModeling #NaturalKeys #SurrogateKeys #EnterpriseArchitecture #DatabaseDesign #AIArchitecture #DataEngineering #TechLeadership
Our website uses cookies to enhance your experience. Check Out
Ok, Go it!