From Class Diagram to Database & Code
From Class Diagram to Database & Code
A class diagram is not just documentation — it is a blueprint. Once your domain model is stable, you can mechanically translate it into two deliverables that developers care about most: a relational database schema and source-code class skeletons. Understanding this translation is one of the most practical skills a systems analyst can master, because it bridges the gap between analysis and implementation.
Why the Mapping Matters
Developers frequently receive a class diagram from analysts and must produce working code and a database from it. When the translation rules are applied consistently, the result is a schema whose tables mirror the domain, foreign keys that match associations, and class files whose fields and methods follow directly from the model. Errors in the mapping — such as ignoring multiplicity or missing an association class — are expensive to fix once data starts accumulating.
Rule 1 — Each Class Becomes a Table
Every concrete class in the diagram maps to a table. The class name becomes the table name (usually plural in practice). Each attribute becomes a column, and the UML type maps to a database type:
String→VARCHARInteger→INTBoolean→TINYINT(1)orBOOLEANDate/DateTime→DATE/DATETIMEDecimal→DECIMAL(p,s)
Every table also gets a surrogate primary key (id) unless the model specifies a natural key. In code, the class becomes a file with private fields and getter/setter methods (or public properties depending on the language).
Rule 2 — Associations Become Foreign Keys
The multiplicity of an association determines exactly how the foreign key is placed:
- One-to-Many (1 → 0..*) — the foreign key lives on the many side. For example, an
Orderbelongs to oneCustomer: theorderstable gets acustomer_idcolumn. - One-to-One (1 → 0..1) — the foreign key lives in the weaker/optional side. A
Patienthas one optionalMedicalRecord: themedical_recordstable gets apatient_id(unique). - Many-to-Many (* → *) — a junction table is required. It has two foreign keys — one to each side — and its own primary key (or a composite one).
In code, a one-to-many association becomes a collection field on the one side (e.g., List<Order> orders) and a reference field on the many side (e.g., Customer customer).
Rule 3 — Aggregation and Composition
Aggregation maps the same way as a regular association — a foreign key on the part side (or a junction table for many-to-many). The distinction is semantic, not structural, in the database. In code, the "whole" class holds a reference or collection to the "part".
Composition signals a stronger ownership: the part cannot exist without the whole. In the database, add ON DELETE CASCADE to the foreign key so that deleting the whole automatically removes its parts. In code, the whole is responsible for creating and destroying its parts.
Rule 4 — Inheritance Strategies
Inheritance has three common mapping strategies in relational databases:
- Single Table Inheritance (STI) — one table for the entire hierarchy with a
typediscriminator column. Simple but wastes space with NULLs for subclass-specific columns. - Class Table Inheritance (CTI) — one table per class in the hierarchy; the subclass table's primary key is also a foreign key to the parent table. Normalized but requires JOINs.
- Concrete Table Inheritance — one table per leaf class, with all parent attributes duplicated. Fast reads but data duplication.
In code, the class hierarchy maps directly: the parent class (or abstract class) is the base; subclasses extend it and inherit attributes and methods.
order_items junction table.Rule 5 — Association Classes Become Junction Tables
When a many-to-many relationship carries its own attributes (an association class), those attributes become columns in the junction table. In the diagram above, OrderItem holds quantity and unitPrice: these become columns in the order_items table alongside the two foreign keys.
Rule 6 — Abstract Classes and Interfaces
Abstract classes do not get their own table when using Concrete Table Inheritance, but do get one in Class Table Inheritance. Interfaces have no database mapping — they are a code-only concept. In code, abstract classes become abstract class declarations; interfaces become interface declarations with method signatures and no implementation bodies.
payments table.Code Skeleton Example
Translating to code is equally mechanical. Consider the Order class from the online store. A typical object-oriented skeleton looks like this:
Notice how each UML attribute becomes a private field, each association becomes a reference or collection, and each UML operation becomes a method. The constructor enforces the mandatory association (an Order must have a Customer).
OrderItem → order_items). Consistent naming avoids confusion between the model and the implementation.
Address inside a Customer) as a bag of string attributes on the parent class. This breaks normalization and hides the structure. Model it as a separate class, then decide in the database whether to give it its own table or embed it as columns (an acceptable trade-off for simple value objects, but make it a conscious choice).
Checklist: Class Diagram to Database
- Every concrete class → one table.
- Every attribute → one column (with the correct SQL type).
- One-to-many association → FK on the many-side table.
- Many-to-many association (with or without association class) → junction table with two FKs.
- Composition → add
ON DELETE CASCADEto the FK. - Inheritance → choose STI, CTI, or Concrete Table and apply consistently.
- Abstract classes → table only in CTI (holds shared columns).
- Interfaces → no table, no columns — code only.
With these rules in hand, you can hand a developer a class diagram and a mapping decision sheet, and they will be able to build a correct database and code structure without guessing. That precision is the hallmark of a professional systems analyst.