Featured image

Table of Contents Link to heading

What Logical Design Produces Link to heading

Logical design is the bridge between conceptual modelling and physical implementation. The input is a validated UML diagram; the output is a set of relational schemas — written descriptions of every table, its attributes, its Primary Key, its Candidate Keys, and its Foreign Key references.

A relational schema uses this notation:

RelationName(attribute1, attribute2, attribute3)
PK(attribute1)
CK(attribute2)
FK(attribute3) ~> OtherRelation(otherAttribute)

This stage also resolves any remaining PK decisions — choosing between Candidate Keys where multiple exist. Refer to the Primary Key selection rules for guidance.

Logical design can be performed manually (as covered here) or assisted by tooling: MS SQL Server Diagram Designer, Lucidchart, DBDesigner Fork, and ArgoUML all support UML-to-schema translation.

Translation Rule: Classes Link to heading

Every UML Class becomes a relation of the same name. The Primary Key defined in the class becomes the relation’s PK.

Example — given this association diagram:

Example

Student(studentID, emailID, studentName)
PK(studentID)
CK(emailID)
Course(courseID, courseName)
PK(courseID)
CK(courseName)

Each class is translated independently first. Associations between classes are handled in the next step.

Translation Rule: Associations and Multiplicities Link to heading

The multiplicity on an association line determines where Foreign Keys are placed and whether a junction table is needed.

One-to-One (1:1) Link to heading

In a 1:1 relationship, either side can hold the FK. The convention is: if one side has a minimum cardinality of 0 (optional participation), that side holds the FK — this way, a NULL FK is acceptable without creating an orphaned mandatory record.

Example:

One-to-One

Person(personID, personName, dateOfBirth)
PK(personID)
AustralianPassport(passportNo, dateIssued, dateExpired, personID)
PK(passportNo)
FK(personID) ~> Person(personID)

AustralianPassport holds the FK because not every Person has an Australian passport — the relationship is optional on the Person side. A Person can exist without a passport, but a passport cannot exist without a person.

One-to-Many (1:*) and Many-to-One (*:1) Link to heading

The FK goes on the “many” side — place the PK from the “one” side into the “many” side as a FK.

Example:

One-to-Many

Course(courseID, courseName)
PK(courseID)
Tutorial(classNo, location, courseID)
PK(classNo)
FK(courseID) ~> Course(courseID)

A Course has many Tutorial instances; each Tutorial belongs to exactly one Course. The Tutorial relation holds courseID as a FK — this is the standard pattern for all one-to-many relationships.

Many-to-Many (*:*) Link to heading

A many-to-many relationship requires a junction table (also called an association table or bridge table). The junction table holds the PKs of both participating relations as FKs, and the combination of these FKs typically forms the junction table’s composite PK.

If the association has its own attributes (an Association Class in the conceptual model), those attributes are included in the junction table.

Example — including an Association Class with dateCommenced and mark:

Many-to-Many with Association Class

Student(studentID, emailID, studentName)
PK(studentID)
CK(emailID)
Course(courseID, courseName)
PK(courseID)
Enrolment(studentID, courseID, dateCommenced, mark)
PK(studentID, courseID)
FK(studentID) ~> Student(studentID)
FK(courseID)  ~> Course(courseID)

The junction table Enrolment exists because the many-to-many relationship itself carries data (dateCommenced, mark) that belongs to the specific pairing of student and course — not to either entity independently.

Note
If no natural name can be found for the junction table, use a combination of the two entity names — StudentCourse, CourseBook, etc. However, a meaningful business name (Enrolment, Registration, Assignment) is always preferred where one exists.

Translation Rule: Recursive Relationships Link to heading

A recursive relationship (self association) produces a separate junction table whose two FK columns both reference the same parent relation — but represent different roles.

Example:

Recursive Relationship

Employee(ID, name)
PK(ID)
Supervision(supervisorID, superviseeID)
PK(supervisorID, superviseeID)
FK(supervisorID) ~> Employee(ID)
FK(superviseeID) ~> Employee(ID)

Both supervisorID and superviseeID reference Employee(ID), but they represent different roles in the relationship. The column names (derived from the role names in the UML diagram) make the distinction explicit.

Translation Rule: Multivalued Attributes Link to heading

A multivalued attribute — one that can hold more than one value per entity instance — violates first normal form and must be resolved before the logical schema is finalised.

Example — if Student has a multivalued address attribute:

Student(studentID, emailID, studentName, address)

Multivalued attribute

Resolution: move the multivalued attribute into a new table, linked back to the original by a FK (typically a Surrogate Key generated for the new table):

Student(studentID, emailID, studentName, addressID)
PK(studentID)
CK(emailID)
FK(addressID) ~> Address(addressID)
Address(addressID, street, suburb, postcode)
PK(addressID)

The Address table now holds one address per row. A student with multiple addresses has multiple rows in Address, each referencing the student’s addressID.

Tip
When decomposing multivalued attributes, check whether the new table itself contains multivalued or composite attributes. The decomposition must produce a 1NF-compliant table — not just move the problem somewhere else.

Translation Rule: Inheritance Link to heading

Inheritance hierarchies (Generalisation/Specialisation) can be translated using two strategies: vertical or horizontal. The choice depends on query patterns and the degree to which subclasses share common attributes.

Example hierarchy:

Inheritance Example

Vertical Inheritance Link to heading

In vertical inheritance, the superclass is translated into its own relation. Each subclass is also translated into its own relation, inheriting the superclass PK as both its own PK and as a FK referencing the superclass.

Person(personID, personName)
PK(personID)
Staff(personID, position)
PK(personID)
FK(personID) ~> Person(personID)

Student(personID, gpa)
PK(personID)
FK(personID) ~> Person(personID)

Contractor(personID)
PK(personID)
FK(personID) ~> Person(personID)

Characteristics:

  • Superclass table exists and holds shared attributes
  • Querying a complete entity (e.g., a staff member with their name) requires a JOIN between Person and Staff
  • Supports optional participation — a Person can exist without being in any subclass
  • Adding a new subclass requires only a new table; the superclass is unchanged
  • Best when: subclasses have many distinct attributes; the superclass is queried independently; entities may belong to multiple subclasses (non-disjoint)

Horizontal Inheritance Link to heading

In horizontal inheritance, no superclass table is created. Each subclass is translated into its own complete relation, inheriting (duplicating) the superclass attributes directly.

Staff(personID, personName, position)
PK(personID)

Student(personID, personName, gpa)
PK(personID)

Contractor(personID, personName)
PK(personID)

Characteristics:

  • No superclass table — shared attributes are replicated into every subclass
  • Querying a specific subclass requires no JOINs — all data is in one table
  • Adding a new shared attribute requires updating every subclass table
  • Cannot represent a person who is not in any subclass (mandatory participation assumed)
  • Best when: subclasses are always disjoint; all entities must belong to a subclass; query performance on individual subclasses is critical

Choosing Between Vertical and Horizontal Link to heading

Consideration Vertical Inheritance Horizontal Inheritance
Superclass table Yes No
JOIN required to query a full entity Yes No
Supports optional participation Yes No (entity must be a subclass)
Supports overlapping subclasses Yes No (duplicates would result)
Schema maintenance overhead Low (shared attrs in one place) Higher (shared attrs duplicated)
Query performance on subclasses Lower (JOIN needed) Higher (single table)

Vertical inheritance is the default choice for most enterprise schemas. Horizontal inheritance is appropriate for simple, disjoint hierarchies where query performance on subclass data is the primary concern.