All articles

Improve a Bad Legacy Schema Behind a Code Boundary

Hide cryptic tables behind repositories and meaningful types, regain control in code, then approach improvements to the legacy database.

Source and AI note: This article is based on Gemini’s Devpractice on YouTube. It was generated and edited with the gpt-5.6-sol model.

When a legacy database is full of cryptic table and column names, renaming the schema first may be the riskiest possible starting point. Put a repository or adapter boundary over the database, expose meaningful typed results to the application, and stop the bad vocabulary from spreading. Improve the database after the code has regained some control.

This is an incremental strategy for a system that still runs. If the code passes query results through generic maps, this code-first approach may not provide enough leverage and a broader improvement may be needed.

Draw a line below the raw schema

Imagine application methods that contain SQL against tables named only by codes. Every caller has to know both the business meaning and the database riddle. The first useful boundary gathers those queries into a repository-like component.

Above that line, return a type named for what the data means, containing only the fields the use case needs. Below it, the adapter may still issue the ugly query. This does not repair the schema, but it prevents another layer from learning its accidental names.

Static types add leverage here. The compiler can show where a meaningful result is consumed and which fields are actually used. A generic map preserves much less information and may make the incremental route too weak.

Learn the meaning while containing the damage

The boundary is not only cosmetic. Moving query access into one place helps reveal that a coded table represents products, that only two of ten selected columns matter, or that several joins serve one business operation. That knowledge can then shape better names and smaller interfaces.

Do not invent meanings from the table name. Search for where it is used, read the current code, and discover what the coded tables and fields mean. The exact table relationships in this case remain unknown.

Once application code depends on meaningful interfaces instead of raw schema details, later changes can remain behind that boundary instead of spreading the schema vocabulary back through callers.

Change the database after the leak is contained

After raw table and column names stop leaking through application code, database improvement can follow behind the boundary. The concrete table and relationship details are unknown, so only the order is clear here: contain the schema vocabulary in code, expose meaningful types, and then approach the database.

Starting in code also uses static types and compiler feedback while the legacy database remains contained.